Kosten für Mutex, kritischen Abschnitt usw. unter Windows

8

Ich habe irgendwo gelesen, dass der Overhead eines Mutex nicht so viel ist, weil die Kontextumschaltung nur im Falle einer Konkurrenz stattfindet.

Auch bekannte Futexes in Linux.

Gilt das Gleiche in Windows? Ist Critical Section eine passendere Map zu Mutexe in Linux.

Nach allem, was ich herausgefunden habe, bieten Critical Sections im Vergleich zu Mutex eine bessere optimale Leistung, gilt das für jeden Fall?

Gibt es einen Eckfall, in dem Mutexe in Windows schneller als ein kritischer Abschnitt sind.

Angenommen, nur ein einzelner Prozess - Threads greifen auf die Mutexe zu (nur um den anderen Vorteil kritischer Abschnitte zu eliminieren)

Hinzugefügt Info: Betriebssystem Windows Server,
             Sprache C ++

    
Desert Ice 06.08.2013, 13:20
quelle

2 Antworten

12

Wenn man den spezifischen Zweck von Critical Sections und Mutexes betrachtet, denke ich nicht, dass Sie eine Frage zu den Kosten stellen können, da Sie keine Alternative haben, wenn mehrere Threads die gleichen Daten berühren müssen. Offensichtlich, wenn Sie nur eine Zahl erhöhen / verringern müssen, können Sie die Interlocked*() -Funktionen auf einer volatile -Nummer verwenden und Sie können loslegen. Aber für etwas Komplexeres müssen Sie ein Synchronisationsobjekt verwenden.

Beginnen Sie Ihre Lektüre hier auf der Synchronisationsobjekte, die unter Windows verfügbar sind ^ . Alle Funktionen sind dort aufgelistet, gut gruppiert und gut erklärt. Einige sind nur Windows 8.

Was Ihre Frage angeht, sind Critical Sections weniger teuer als Mutexe s, da sie für den gleichen Prozess ausgelegt sind. Lesen Sie this ^ und this ^ oder nur das folgende Zitat.

  

Ein kritisches Section-Objekt bietet eine Synchronisation ähnlich der, die von einem Mutex-Objekt bereitgestellt wird, außer dass ein kritischer Abschnitt nur von den Threads eines einzelnen Prozesses verwendet werden kann. Ereignis-, Mutex- und Semaphor-Objekte können auch in einer Einzelprozessanwendung verwendet werden, kritische Objektbereiche bieten jedoch einen etwas schnelleren und effizienteren Mechanismus für die gegenseitige Ausschluss-Synchronisation (eine prozessorspezifische Test- und Setzanweisung). Wie bei einem Mutex-Objekt kann ein kritisches Abschnittsobjekt jeweils nur einem Thread gehören, was es nützlich macht, eine gemeinsam genutzte Ressource vor gleichzeitigem Zugriff zu schützen. Im Gegensatz zu einem Mutex-Objekt gibt es keine Möglichkeit, festzustellen, ob ein kritischer Abschnitt aufgegeben wurde.

Ich verwende Critical Sections für die gleiche Prozesssynchronisation und Mutexes für die prozessübergreifende Synchronisation. Nur wenn ich wirklich wissen muss, ob ein Synchronisationsobjekt aufgegeben wurde, benutze ich Mutexes in der gleiche Prozess.

Also, wenn Sie ein Synchronisationsobjekt benötigen, ist die Frage nicht, was die Kosten sind, sondern was billiger ist. Es gibt wirklich keine andere Alternative als eine Speicherbeschädigung.

PS : Es könnte Alternativen wie die einer, der in der ausgewählten Antwort hier erwähnt wird ^ , aber ich gehe immer auf die plattformspezifische Kernfunktionalität oder die plattformübergreifende Ausrichtung. Es ist immer schneller! Wenn Sie also Windows verwenden, verwenden Sie die Tools von Windows:)

AKTUALISIEREN

Je nach Ihren Anforderungen können Sie möglicherweise die Notwendigkeit von Synchronisierungsobjekten reduzieren, indem Sie so viel wie möglich eigenständige Arbeit in einem Thread ausführen und die Daten nur am Ende oder von Zeit zu Zeit kombinieren.

Dummes Beispiel : Nehmen Sie eine Liste mit URLs. Sie müssen sie abkratzen und analysieren.

  1. Werfen Sie eine Reihe von Threads ein und beginnen Sie, URLs nacheinander aus der Eingabeliste auszuwählen. Für jeden Ihrer Prozesse zentralisieren Sie die Ergebnisse so wie Sie es tun. Es ist Echtzeit und cool
  2. Oder Sie können die Threads einwerfen, die jeweils eine Scheibe der Eingabe-URLs haben. Dies beseitigt die Notwendigkeit, den Auswahlprozess zu synchronisieren. Sie speichern das Analyseergebnis im Thread und am Ende kombinieren Sie das Ergebnis nur einmal. Oder nur einmal alle 10 URLs sagen wir mal. Nicht für jeden von ihnen. Dies reduziert die Synchronisationsvorgänge drastisch.

So können Kosten gesenkt werden, indem Sie das richtige Werkzeug auswählen und überlegen, wie Sie die Sperre verringern und entsperren. Aber Kosten können nicht entfernt werden:)

PS : Ich denke nur in URLs:)

UPDATE 2:

Hatte die Notwendigkeit in einem Projekt, etwas zu messen. Und die Ergebnisse waren ziemlich überraschend:

  • Ein std::mutex ist am teuersten. (Preis der plattformübergreifenden)
  • Ein Windows-natives Mutex ist 2x schneller als std .
  • Ein Critical Section ist 2x schneller als das native Mutex .
  • Ein SlimReadWriteLock ist + -10% von Critical Section .
  • Meine hausgemachte InterlockedMutex (spinlock) ist 1,25x - 1,75x schneller als die Critical Section .
CodeAngry 06.08.2013, 23:35
quelle
0

Wenn ich std :: mutex in Windows 8 verwende, bekomme ich normalerweise 3-4x Verbesserung (bei nicht konkurrierendem Fall), indem ich meine eigene benutzerdefinierte Drehsperre verwende:

Mutex basiert

%Vor%

});

hausgemachtes Schloss frei

%Vor%

Tests werden auf x86 gemacht.

Ich habe nicht herausgefunden, was std :: mutex in Fenstern unterstreicht, weil es viel Code generiert.

    
Ghita 05.12.2013 10:30
quelle