Menu

Possibility to store persistent memory on RAM or Disk?

Edward Lau
2014-03-05
2014-03-07
  • Edward Lau

    Edward Lau - 2014-03-05

    Hello,

    The project I am working with requires memory storage across measurements, since the reconstruction pipeline requires several recent measurements to fill the undersampled data, a persistent memory storage might be necessary.

    The simplest way to do it is to store the information in simple array form, but it might not be fast enough for real-time reconstruction.
    Therefore, I would like to ask if there are any advisable approaches to store arrays on RAM or Disk even if another measurement begins and calls for the array stored in previous measurements.

    I am looking for your advice.

    Yours truly,
    Edward Lau

     
    • Michael Hansen

      Michael Hansen - 2014-03-05

      Hi Edward,

      This is something that we have been thinking about putting in for a while.
      It is not really that complicated, we have just not had much use for it.

      The easiest is, as you say, to simply store some files on disk. There are
      some problems with this approach:

      1. There could be a performance hit, but in most cases this will probably
        not be an issue.
      2. Some users may find it unattractive that files are left on the disk
        after the recon is done. You could fill up the disk and have strange
        failure modes. But again that can be mitigated.

      The advantage is that the data is persistent, even if the Gadgetron
      computer is rebooted or the Gadgetron is restarted. For that reason alone,
      there are probably things that should be stored on disk. Such as hardware
      characterizations, etc.

      The second option is to create a process wide singleton (
      http://en.wikipedia.org/wiki/Singleton_pattern) in the Gadgetron and use
      this class to park memory objects that can be retrieved later. It is easy
      to create a singleton (look at the CPU based FFT, it uses a singleton to
      insure that only one process accesses the planning routines at any given
      time). You would need to implement some kind of storage system in this
      singleton. You could store ACE_Message_Block pointers in some data
      structure that would allow you to retrieve them with a name tag.

      In practice there is some work to be done to make this work well. You need
      to think about the life cycle of these memory objects. Should they exist
      forever or be cleaned up at some point? The risk is that you could fill up
      your memory over time (a much worse scenario that the disk issue) with no
      safe way of determining which objects can be deleted.

      In practice there is a need for both the disk based and the RAM based
      solution in the long run, but it is only really the disk based that we have
      used.

      Hope this helps,
      Michael

      On Wed, Mar 5, 2014 at 2:32 AM, Edward Lau edward-lau@users.sf.net wrote:

      Hello,

      The project I am working with requires memory storage across measurements,
      since the reconstruction pipeline requires several recent measurements to
      fill the undersampled data, a persistent memory storage might be necessary.

      The simplest way to do it is to store the information in simple array
      form, but it might not be fast enough for real-time reconstruction.
      Therefore, I would like to ask if there are any advisable approaches to
      store arrays on RAM or Disk even if another measurement begins and calls
      for the array stored in previous measurements.

      I am looking for your advice.

      Yours truly,
      Edward Lau


      Possibility to store persistent memory on RAM or Disk?https://sourceforge.net/p/gadgetron/discussion/general/thread/3aefb7f0/?limit=25#304e

      Sent from sourceforge.net because you indicated interest in
      https://sourceforge.net/p/gadgetron/discussion/general/

      To unsubscribe from further messages, please visit
      https://sourceforge.net/auth/subscriptions/

       
      • Edward Lau

        Edward Lau - 2014-03-07

        Hello Dr. Hansen,

        Maybe I am not skilled enough, but I failed to wrap my head around the idea that the same ACE_MESSAGE_BLOCK on Gadgetron can ever survive multiple measurements.
        Even during offline environment, the data going through Gadgetron came and went, and the data including the pointer reserved for persistent memory will eventually lost when the measurement ends, and the image is going back to the client.

        Maybe this is why you told me to save the pointer in some data structure in order to retrieve it later. However, I am uncertain if the memory assigned for the array will be disturbed by incoming data from another measurement.

        The plan goes something like this.
        I will output the location where the pointer pointed in txt form, and I will read the txt in later measurements when I need it, and I will point a pointer into that position written on the txt. When I don't need the persistent memory anymore, I proceed to release the memory to prevent permanent memory leak.
        You might want to call this a "deliberate and temporary memory leak", I guess.

        This might be risky, and this might go against the convention, so I am asking for a second opinion just to be sure.

        Also, I would like to ask if it is possible to transit from Gadget2 to Gadget3 and vice versa, by connecting or disconnecting the ACE_DATA_BLOCK with something like m2->cont(m3) and m3->release().

        Thanks,
        Edward

         
        • Thomas Sangild Sørensen

          Hi Edward

          Let me try to clarify some of your questions.

          First of all, you are absolutely right, once the Ace_Message_Block (i.e. GadgetContainerMessage) reaches the end of the chain, its memory will be deleted. You could make a copy of the data you wish to save. In the gpuRadialPrepGadget we keep an internal buffer of profile copies using the method:

          gpuRadialSensePrepGadget::duplicate_profile( GadgetContainerMessage< hoNDArray< std::complex<float> > > *profile )
          {
            GadgetContainerMessage< hoNDArray< std::complex<float> > > *copy = 
              new GadgetContainerMessage< hoNDArray< std::complex<float> > >();
          
            *copy->getObjectPtr() = *profile->getObjectPtr();
          
            return copy;
          }
          

          You would want to do something similar, probably starting with the container message containing the acquisition/image header and subsequently its continuations. This copy will be valid pointer for as long as the gadgetron server is running - until the ACE_MESSAGE_BLOCK is explicitly released. And once you stop the gadgetron your data is lost.

          Safer (but slower) than writing out just the pointers to disk, would be writing out the actual array. To be sure you are aware, for the NDArray class we have functionality for reading/writing to disk in hoNDArray_fileio.h. Unless you intend to put more info that merely the data pointers in your text file, I would instead make an hoNDArray<size_t> containing these pointers and use the functionality already present to read/write the arrays.</size_t>

          And yes, this is risky and you need to be careful about how you do this. If you do it incorrectly, your memory heap is immediately corrupted.

          You can easily connect gadgets of type Gadget2 and Gadget3. If you have two message block connected already, simply use the 'cont()' on the latter to assign a third continuation - as you suggest. But do NOT call m3->release, which will delete the memory of m3 making it an invalid continuation. At the end of the gadget chain a call to m1->release() will go through the chain of message blocks and delete m1 and all its continuations.

          Hope this gets you on your way... And keep us posted, you are moving into a territory we have often discussed but never actually entered.

          / Thomas

           
  • Michael Hansen

    Michael Hansen - 2014-03-07

    I agree with Thomas' comments and I will add:

    DO NOT store pointers in a text file.

    That is just a really really bad idea for more reasons than I care to enumerate right here. You need to a) duplicate the ACE_Message_Block (or GadgetContainerMessage) as Thomas explained and then b) store the ACE_Message_Block in some kind of globally available (but unique) object, preferably a singleton with some identifiers. You could for instance use a std::map< std::string, ACE_Message_Block> to create a lookup table where you could find the stored data by name. You also don't have to use the ACE_Message_Block or GadgetronContainerMessage infrastructure for this, you could use any kind of generic way of storing it. The ACE_Message_Block approach, however, gives a generic point to store so your storage infrastructure would be able to handle heterogenous data.

    Hope this helps,
    Michael

     
MongoDB Logo MongoDB