2014-06-15 15 views
9

Funktionieren die Linux glibc pthread-Funktionen auf x86_64 als Zäune für schwach geordnete Speicherzugriffe? (pthread_mutex_lock/unlock sind genau die Funktionen, die mich interessieren).Pthreads v. SSE schwache Speicherordnung

SSE2 bietet einige Anweisungen mit schwacher Speicherordnung (nicht temporäre Speicher wie insbesondere movntps). Wenn Sie diese Anweisungen verwenden und sicherstellen möchten, dass ein anderer Thread/Kern eine Bestellung sieht, dann verstehe ich, dass Sie dafür einen expliziten Zaun benötigen, z. B. eine sfence-Anweisung.

Normalerweise erwarten Sie, dass die Pthread-API entsprechend als Zaun fungiert. Ich vermute jedoch, dass normaler C-Code auf x86 keine schwach geordneten Speicherzugriffe generiert, daher bin ich nicht zuversichtlich, dass Pthreads als Zaun für schwach geordnete Zugriffe dienen muss.

Beim Lesen des glibc pthread-Quellcodes wird ein Mutex am Ende mit "lock cmpxchgl" implementiert, zumindest auf dem unbetonten Pfad. Ich vermute also, dass das, was ich wissen muss, ist, dass diese Anweisung als ein Zaun für schwach geordnete SSE2-Zugriffe dient?

+0

Nun, niemand antwortete, also rollte ich die Ärmel hoch und schrieb ein Testprogramm. Bisheriger Fortschritt: ------ * Mit pthread spinlocks kann ich leicht zeigen, dass sie keine Zäune sind. * Ich habe es versäumt, PThread-Mutexe zu produzieren, die nicht als Zäune dienen. ------ Ich bin mir nicht sicher, ob der Misserfolg ist, weil die Mutexe Zäune sind oder weil ich nur Glück gehabt habe. Mein Testcode ist bei https://gist.github.com/rcls/c855e3e782253e58e046 – user1998586

Antwort

4

Temporäre Speicher müssen sfence Anweisungen ordnungsgemäß bestellt werden.

Die effiziente Implementierung eines einfachen Mutex auf Benutzerebene setzt jedoch voraus, dass sie durch einfaches Schreiben freigegeben wird, was im Gegensatz zu atomaren Read-Modify-Write-Operationen wie lock cmpxchg, die vollen Speicher implizieren, nicht zu Schreibpuffern führt Zaun.

So haben Sie eine Situation, wenn die unlock keinen Effekt von store-with-release semantischen für nicht-temporären speichert angewendet hat. Somit können diese SSE-Speicher nach dem Entsperren neu angeordnet werden und nachdem ein anderer Thread den Mutex erwirbt.

+0

Danke, ich hatte nur über die Lock-Operation gedacht und verpasst, dass die Reihenfolge Semantik der Entsperrung nach dem schwach geordneten Speicher ist, was kritisch ist . – user1998586

+0

Und erneut den glibc Quellcode lesen, dies stimmt mit den Ergebnissen meiner Tests überein. pthread_mutex_unlock, das als Zaun zu fungieren scheint, verwendet eine gesperrte Anweisung (über Lowlevellock). pthread_spin_unlock verwendet einen normalen Speicher. [Der andere Unterschied ist, dass pthread_spin_unlock schneller ist - wahrscheinlich würden alle ausreichend langsamen Operationen in der Praxis hier einen Zaun bilden, auch wenn die Architekturbeschreibung es nicht garantiert.] – user1998586