Boost interprocess vs. Win32API: Unterschied zwischen den Versionen

Aus Software Entwicklung Projekte
Wechseln zu: Navigation, Suche
(Ergebnis Win32API)
Zeile 36: Zeile 36:
 
</pre>
 
</pre>
  
=== Ergebnis Boost 1.58===
+
== Ergebnis Boost 1.58==
  
 
Der entwickelte Serverprozess hatte eine CPU Last von 2.5%, obwohl dieser im Leerlauf war. Die Last ist einfach nur durch das Warten begrenzt durch einen timeout entstanden.
 
Der entwickelte Serverprozess hatte eine CPU Last von 2.5%, obwohl dieser im Leerlauf war. Die Last ist einfach nur durch das Warten begrenzt durch einen timeout entstanden.
Zeile 42: Zeile 42:
 
Mögliches weiteres Problem: Was bewirkt eine Zeitumstellung bei einem Timeout mit absoluter Zeitangabe?
 
Mögliches weiteres Problem: Was bewirkt eine Zeitumstellung bei einem Timeout mit absoluter Zeitangabe?
  
== Win32 API ==
+
= Win32 API =
  
 
Ich habe alle Stellen ausgetauscht gegen SRWLOCK und CONDITION_VARIABLE, die seit Windows 2008 bzw. Vista unterstützt werden (nicht unter XP oder W2003 bzw. älter). Der neue Code ist fast identisch zu dem Alten.
 
Ich habe alle Stellen ausgetauscht gegen SRWLOCK und CONDITION_VARIABLE, die seit Windows 2008 bzw. Vista unterstützt werden (nicht unter XP oder W2003 bzw. älter). Der neue Code ist fast identisch zu dem Alten.
Zeile 84: Zeile 84:
 
</pre>
 
</pre>
  
=== Ergebnis Win32API ===
+
== Ergebnis Win32API ==
  
 
Die Last des Servers im Leerlauf ist auf unter 0.01% gesunken.  
 
Die Last des Servers im Leerlauf ist auf unter 0.01% gesunken.  

Version vom 18. Juni 2015, 11:48 Uhr

Boost interprocess

Folgende C++ Klassen habe ich unter VS2013/Win8.1/64bit eingesetzt um Threads zu synchronisieren bzw. Code zu schützen.

Eingesetzt habe ich die Boost 1.58 (Stand 18.06.2015).

boost::interprocess::interprocess_mutex      MyMutex;
boost::interprocess::interprocess_condition  MyCondition;
boost::interprocess::interprocess_semaphore  MySemaphore;

Dabei habe ich komplette Funktionen mittels scoped_lock gesperrt:

boost::interprocess::scoped_lock<boost::interprocess::interprocess_recursive_mutex> lock(reentrant_block);

Desweiteren habe ich Signale für bestimmte Aktionen über die Condition ausgelösst:

void func1()
{
  ...
  MyCondition.post();
  ...
}

void func2()
{
  ...
  boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(cond_read_mutex);  
  bool ret = cond_read_possible.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(timeoutMS));
  ...
}

Ergebnis Boost 1.58

Der entwickelte Serverprozess hatte eine CPU Last von 2.5%, obwohl dieser im Leerlauf war. Die Last ist einfach nur durch das Warten begrenzt durch einen timeout entstanden.

Mögliches weiteres Problem: Was bewirkt eine Zeitumstellung bei einem Timeout mit absoluter Zeitangabe?

Win32 API

Ich habe alle Stellen ausgetauscht gegen SRWLOCK und CONDITION_VARIABLE, die seit Windows 2008 bzw. Vista unterstützt werden (nicht unter XP oder W2003 bzw. älter). Der neue Code ist fast identisch zu dem Alten.

SRWLOCK reentrant_block
SRWLOCK cond_write_srw;
CONDITION_VARIABLE cond_write_possible;

void Init()
{
  InitializeSRWLock(&reentrant_block);

  InitializeSRWLock(&cond_write_srw);
  InitializeConditionVariable(&cond_write_possible);
}

void func_protected()
{
  AcquireSRWLockShared(&reentrant_block);
  ...
  ReleaseSRWLockShared(&reentrant_block);
}

void func_signal()
{
  WakeAllConditionVariable(&cond_write_possible);
}

void func_wait_signal()
{
  AcquireSRWLockShared(&cond_write_srw);
  BOOL ret = SleepConditionVariableSRW(&cond_write_possible, &cond_write_srw, timeoutMS, CONDITION_VARIABLE_LOCKMODE_SHARED);

  ... // Hier muss noch ret ausgewertet werden
  ... // geschützter Code

  ReleaseSRWLockShared(&cond_write_srw);
}

Ergebnis Win32API

Die Last des Servers im Leerlauf ist auf unter 0.01% gesunken.

Ein Test unter Last hat ergeben, dass der gesamte Prozess um 80% schneller abläuft. Dies ist aber auch ein Hinweis, dass ich in meinem Design zu sehr von schnellen Locks abhängig bin.