Kosten einer CriticalSection



  • Hi zusammen

    da ich einen Bereich habe, den ich schützen muss, der aber sehr sehr oft durchlaufen wird, habe ich mir Gedanken über die Kosten einer CriticalSection gemacht, wenn sie NICHT kollidiert.

    Das Testszeniaro habe ich in dem Fall unter Windows aufgebaut
    mit der klassischen CRITICAL_SECTION aus der Windows API.

    Dann habe ich 1.000.000 mal Enter und Leave gespielt und die Zeit gemessen.

    Herausgekommen ist ein Wert von
    75 ns
    pro einem nicht-kollidierenden Durchlauf.

    Da mein Bereich in der finalen Version der Applikation vermutlich ca. 10.000 bis 100.000 mal pro Sekunde durchlaufen wird, mache ich mir Sorgen, da mich das dann schlimmstenfalls einstellige Millisekunden nur für die CS kosten wird.

    Meine Frage an euch:
    Gibt es Alternativen, um einen bestimmten Speicherbereich ( in meinem Fall nur ein Pointer ) etwas zeiteffizienter zu schützen? atomic evtl.?

    gruß Tobi



  • ne CRITICAL_SECTION ist die rudimentärste form des schutzes in windows, also die wo die wenigstens anforderungen umgesetzt wurden.
    d.h. das ding ist performance und nicht auf breite verwendung und komfort ausgelegt.

    und da fast alle mechanismen in der art auf atomic operationen aufbauen (müssen) ... ists sehr wahrscheinlich das die CRITICAL_SECTION im Hintergrund eh nur nen Interface zu nem atomic int irgendwas ++ poll schleife ist ^^

    Wenn es selber implementierst, ist auch wie du auf das "freiwerden" des atomics wartest, das eigentliche Problem, nicht der atomic ...

    10.000 bis 100.000 mal pro Sekunde

    ich denk mal der austausch der CS wird da recht wenig bringen im vergleich zu anderen Themen.
    Parralelität ? gleich direkt in assambler schreiben ?

    Ciao ...



  • Parallel fällt leider aus, weil die Komponente schon ein Teil einer Parallelisierung ist, die nicht noch weiter aufgedröselt werden kann.



  • It0101 schrieb:

    Parallel fällt leider aus, weil die Komponente schon ein Teil einer Parallelisierung ist, die nicht noch weiter aufgedröselt werden kann.

    Kannste zusammendröseln? Statt 1000000000 Objekte zu haben und jedes muss selber mutexten und Du gehst eh linear durch, vielleicht 1000000 Blöcke zu je 1000 Elementen und Du mutextest bloß Blöcke?



  • @It0101
    Ja, klar atomic . Wenns damit geht, und du ein lock/unlock Paar mit einem einzigen atomic-Zugriff ersetzen kannst, sollte das die Kosten etwa halbieren.
    Bzw. sind "read acquire" und "store release" auf Intel quasi gratis, könnte also u.U. noch wesentlich billiger werden, je nachdem was für Zugriffe du brauchst.

    ps:
    75ns sind etwas viel. Bist du sicher dass du richtig gemessen hast? Bei meiner letzten Messung bin ich auf ca. 40+40 Cycles gekommen (lock+unlock), also eher so 20~25ns insgesamt.



  • Etwas schneller als CS auf Windows könnten Slim Reader/Writer Locks sein. Wenn es aber eine triviale atomic-Implementierung gibt, ist die natürlich vorzuziehen.



  • Ja, SRW Locks sind gut. 👍
    boost::mutex wäre auch eine Alternative - das letzte mal wie ich geguckt habe hat boost::mutex zumindest noch eigenen Code verwendet, der sich auch den Bookkeeping-Overhead von CRITICAL_SECTION s spart.

    std::mutex wäre auch OK, wobei da IIRC bei MSVC "unnötiger" Dispatching-Code dazwischen ist und beim Erstellen/Zerstören jeweils eine dynamische Allokation/Deallokation.
    (Weil std::mutex von MSVC halt je nach OS verschiedene Mutex Implementierungen verwendet - also bei älteren OS' halt ne CS und bei neueren IIRC auch die SRW Locks.)
    Der Unterschied dürfte allerdings minimal sein.


Log in to reply