Question

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.

Was it helpful?

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top