Meine Meinung ist, dass die optimale "Spin-Zählung" für die beste Anwendungsleistung zu sehr von der Hardware abhängt, um ein wichtiger Bestandteil einer plattformübergreifenden API zu sein, und Sie sollten wahrscheinlich einfach Mutexe verwenden (in posix, pthread_mutex_init
/ destroy
/ lock
/ trylock
) oder Spin-Locks (pthread_spin_init
/ destroy
/ lock
/ trylock
). Die Begründung folgt.
Was ist der Sinn der Spin-Zählung? Grundsätzlich, wenn der Lock-Besitzer gleichzeitig mit dem Thread läuft, der versucht, den Lock zu erwerben, könnte der Lock-Besitzer den Lock schnell genug freigeben, dass der Aufrufer von EnterCriticalSection die CPU-Kontrolle beim Erlangen des Locks nicht aufgeben müsste, was die Leistung dieses Threads verbessern würde und den Overhead eines Kontextwechsels vermeiden würde. Zwei Dinge:
1: Offensichtlich hängt dies davon ab, dass der Lock-Besitzer parallel zum Thread läuft, der versucht, den Lock zu erwerben. Dies ist auf einem einzigen Ausführungskern unmöglich, was höchstwahrscheinlich der Grund ist, warum Microsoft die Zählung in solchen Umgebungen als 0 behandelt. Auch bei mehreren Kernen ist es durchaus möglich, dass der Lock-Besitzer nicht läuft, wenn ein anderer Thread versucht, den Lock zu erwerben, und in solchen Fällen ist die optimale Spin-Zählung (für diesen Versuch) immer noch 0.
2: Bei gleichzeitiger Ausführung hängt die optimale Spin-Zählung immer noch von der Hardware ab. Unterschiedliche Prozessoren benötigen unterschiedliche Zeiten für ähnliche Operationen. Sie haben unterschiedliche Befehlssätze (die ARM, mit der ich am meisten arbeite, hat keinen Integer-Divisionsbefehl), unterschiedliche Cache-Größen, das Betriebssystem wird verschiedene Seiten im Speicher haben... Das Dekrementieren der Spin-Zählung kann auf einer Load-Store-Architektur eine unterschiedliche Zeit in Anspruch nehmen als auf einer Architektur, bei der arithmetische Befehle direkt auf den Speicher zugreifen können. Selbst auf demselben Prozessor wird dieselbe Aufgabe je nach (mindestens) Inhalt und Organisation des Speichercaches unterschiedliche Zeit in Anspruch nehmen.
Wenn die optimale Spin-Zählung bei gleichzeitiger Ausführung unendlich ist, dann sollten die pthread_spin_*
-Funktionen das tun, was Sie möchten. Wenn sie es nicht ist, verwenden Sie die pthread_mutex_*
-Funktionen.