Search code examples
c++visual-studio-2008boostshared-memoryinterprocess

Speeding up shared memory operations c++


I have a dll application which is written in Visual Studio 2008 VC++. Basicly it has two interface to the external applications.

One of them is for writer:

class writer_interface
{
    virtual void write (myData data, unsigned long id) = 0;
}

and the other one is for the reader apps:

class reader_interface
{
    virtual select(unsigned long id) = 0;
    virtual select(time_t insertionTime) = 0;
}

so I keep my meta data in an container in shared memory which I am using boost managed_shared_memory.

The problem is the external writer application call my write function like 15 times in a second and the readers make query on my shared memory container like 5 times in one second simultaneously.

So for each Write function call for my Write method I have to open shared memory & find my container like that:

//Open the managed segment
managed_shared_memory segment(open_only, "MySharedMemory");
//Find the vector using the c-string name
MyVector *myvector = segment.find<MyVector>("MyVector").first;

but this one is too costly where I have that frequent data. Because each opening shared memory & finding the container in it operation takes almost 100 milliseconds. It means that there is a bottleneck because of that shared memory operations.

Same bottleneck situation occurs for reader apps as well.

My question is how can I make these shared memory operations faster? Is there a way to prevent opening and re-finding the container every time in shared memory?

Thank you.


Solution

  • To cache lately opened segments in memory is a good idea. Suppose that you will cache last 10 opened segments. Create a singleton class that will hold a dictionary that maps string to segment object. Each time you need to read/write from any segment you will check if this singleton includes it already (by some id - its name for example). If yes - you will get its reference/pointer and read/write to it. Otherwise, you will open a new segment and store it in this singleton.

    Singleton is a class that may have only one instance, usually created on first usage. See next link http://forums.codeguru.com/showthread.php?423850-how-to-implement-a-singleton-in-c-c. I would do it like this.

    In header file:

    class Singleton {
    public:
      static Singleton* instance();
      void write (myData data, unsigned long id);
      void select(unsigned long id);
      void select(time_t insertionTime);
    
    private:
      Singleton();
      static Singleton* m_singleton;        // singleton instance
      managed_shared_memory m_segment;
    };
    

    In cpp file: Singleton* Singleton::m_singleton= NULL;

    Singleton::Singleton()
    : segment(open_only, "MySharedMemory")
    {
       // do init stuff
    }
    
    Singleton* Singleton::instance()
    {
      if (m_singleton== NULL)
        m_singleton = new Singleton();
      return m_singleton;
    }
    
    void Singleton::write (myData data, unsigned long id)
    {
      //Find the vector using the c-string name
      MyVector *myvector = m_segment.find<MyVector>("MyVector").first;
    
      // add code here
    }
    
    void Singleton::select(unsigned long id)
    {
    // your code here
    }
    
    void Singleton::select(time_t insertionTime)
    {
    // your code here
    }
    

    Usage in the implementor of write_interface:

    Singleton::instance().write (data, id);
    

    The solution only ensures one instance since program starts until it ends.