atomic<T>::store
-
@Tyrdal sagte in atomic<T>::store:
Und lagst völlig daneben! Lass den Scheiß! Du weißt doch immer noch nicht was ich tue.
Wenn dich doch bloß jemand hier fragen würde, was du eigentlich vor hast
@SeppJ sagte in atomic<T>::store:
Ein Ja oder nein wäre ja auch die korrekte Antwort auf die Frage ob das geht.Hilf dir in Zukunft doch alleine.
-
@Tyrdal "Lass den Scheiss" wiederholt einem Mod zu sagen, der sich erbarmt hat Deine unsinnige Frage zu erforschen, ist einfach unnoetig. Wenn Du ein Experte waerst, der aus research Motivation heraus die Korrektheit von atomic store/loads testen will (allgemein), und nach einer Methode gefragt haettest, mit Verweis auf den Anreiz dieses Vorhabens, dann waere die Antwort sicherlich anders ausgefallen. Wenn jemand so verwirrt anmutet wie Du, dann kann man auch wenig machen, ausser XY zu vermuten.
-
@Columbo sagte in atomic<T>::store:
@Tyrdal "Lass den Scheiss" wiederholt einem Mod zu sagen, der sich erbarmt hat Deine unsinnige Frage zu erforschen, ist einfach unnoetig.
Offensichtlich nicht, denn er lässt es nicht.
Wenn Du ein Experte waerst, der aus research Motivation heraus die Korrektheit von atomic store/loads testen will (allgemein), und nach einer Methode gefragt haettest, mit Verweis auf den Anreiz dieses Vorhabens, dann waere die Antwort sicherlich anders ausgefallen. Wenn jemand so verwirrt anmutet wie Du, dann kann man auch wenig machen, ausser XY zu vermuten.
Ja, hab heute einen schlechten Tag, deswegen musste ich mal fragen. Trotzdem könnte man eher nix sagen als sowas wie oben abzusondern. Der Reiz ist, dass es meine Aufgabe ist das zu tun.
Btw. wieso ist man verwirrt wenn man eine Frage stellt? Und unsinnig ist diese ja nunmal nicht.
-
@Tyrdal sagte in atomic<T>::store:
Du weißt doch immer noch nicht was ich tue.
Naja ich frage mich ob du ein Threading-Problem hast. Also Code hast, welcher sich manchmal recht merkwürdig verhält.
-
@Quiche-Lorraine sagte in atomic<T>::store:
@Tyrdal sagte in atomic<T>::store:
Du weißt doch immer noch nicht was ich tue.
Naja ich frage mich ob du ein Threading-Problem hast. Also Code hast, welcher sich manchmal recht merkwürdig verhält.
Nein, ich habe die Aufgabe zu festzulegen wie man testen kann ob sich eine Implementierung standardkonform verhält und worauf es dabei ankommt. Und heute hatte ich irgendwie ein Brett vorm Kopf.
-
@Tyrdal Ich würde sagen, wenn
std::atomic<T>::is_lock_free
gilt, kann man prüfen ob die korrekten Instruktionen erzeugt werden, wenn es über einen Mutex implementiert wurde, ließe sich durchaus formal zeigen, dass die Implementation korrekt ist."Sicher testen" im Sinne von automatisiertem Unit-Test dürfte allerdings schwer werden, da man auf konkreter Hardware (und all ihren Timings) mit OS und Scheduler nicht wirklich präzise vorgeben kann, wann was und in welchem Thread/auf welchem Core genau passiert. Das ginge vielleicht in einem Emulator, keine Anhnung ob es da welchen mit solchen Funktionalitäten gibt - ich denke schon - in jedem Fall dürfte das aber ziemlich aufwändig werden. Der Nutzen ist auch fraglich, da sich die gängigen Implementierungen schon lange in endlosen Softwareprojekten bewährt haben. Wenn da bei derart grundlegenden Funktionen (auf denen alles andere aufbaut) noch was im argen liegt, dann findet es der "Schwarm" vermutlich recht schnell.
-
@Finnegan Danke für die Antwort, damit kann ich was anfangen.
-
@SeppJ sagte in atomic<T>::store:
Jedenfalls macht es nie Sinn die Implementierung deiner Standardbibliothek zu testen!
Also wir haben schon genug Bugs in diversen Standard-Libraries gefunden. Und auch in Compilern. Und daher haben wir z.T. auch entsprechende Tests in unserer Test-Suite. Normalerweise schreiben wir die nur wenn wir Bugs finden (erst disabled, und dann werden die halt enabled sobald es einen Fix gibt, damit wir merken falls es ne Regression gibt). Bei manchen Dingen wo wir in Vergangenheit oft Probleme hatten haben wir aber auch preventiv Tests geschrieben.
-
@Tyrdal
Ob ein atomic Store wirklich atomar ist kann man nicht alleine prüfen. Aber man kann prüfen ob Store und Load beide atomar sind.Z.B. einfach indem man zwei Threads in einer Schleife laufen lässt von denen einer permanent schreibt und der andere permanent liest. Der schreibende Thread erzeugt dabei Werte nach einem bestimmten prüfbaren Muster, und der lesende Thread prüft ob alle gelesenen Werte diesem Muster entsprechen. (Bzw. man kann auch jeweils mehrere Threads verwenden die Lesen und Schreiben.) Das Muster kann z.B. einfach sein dass bei 32 Bit Werten die Bits 0...15 gleich den Bits 16...31 sind. Die 16 Bits kann man dann entweder durch einen schnellen PRNG erzeugen oder auch einfach durch inkrementieren. Wenn dabei dann ein paar Sekunden lang keine Fehler gefunden wurden, dann hört man auf und erklärt den Test für erfolgreich. Wie bei den meisten Tests garantiert ein fehlerfreier Lauf natürlich nicht dass die Implementierung 100% fehlerfrei ist. Aber ein Test-Fehler ist eine Garantie dafür dass es ein Problem gibt.
Ob der Test funktioniert (also fähig ist Fehler zu finden), kann man prüfen indem man ihn mit normalen, nicht atomaren Variablen laufen lässt. Wobei man da ein bisschen rum-fummeln muss. Auf den meisten Plattformen sind Zugriffe mit <= Registergrösse immer atomar, so lange sie passend aligned sind. Bzw. meistens auch wenn sie nicht passend aligned sind, aber alle Bytes zufällig trotzdem in der selben L1 Cache-Line liegen. D.h. man muss dazu entweder die Alignment-Requirement des Typen verletzen und die Adresse so wählen dass die Bytes der Variable in zwei verschiedenen Cache-Lines liegen. Das ist strenggenommen UB - aber wenn man nur wissen will ob der Test überhaupt fähig ist Fehler zu finden ist es wohl trotzdem OK. Oder man muss z.B. auf 32 Bit Plattformen mit 64 Bit Werten testen. (Wobei manche 32 Bit Plattformen wie x86 durchaus auch 64 Bit Register haben - MMX etc. Je nachdem was der Compiler für Code generiert könnte es da dann passieren dass der Test trotzdem nie Fehler findet.)
Etwas schwieriger ist es die ganze Memory-Ordering Sache zu prüfen. Aber auch da kann man Tests schreiben. Allerdings auch wieder nur in Kombination, z.B. release + acquire. Man kann z.B. in einem Thread eine oder mehrere normale, non-atomic Variablen schreiben, und danach einen "bin fertig" Wert in eine atomic Variable schreiben mit Memory Ordering "release". Ein parallel laufender Thread pollt die atomic Variable mit Memory Ordering "acquire", und wenn der "bin fertig" Wert gelesen wurde liest er die Variablen und prüft ob die erwarteten Werte gelesen wurden. Das ganze wiederholt man dann auch wieder einige tausend bis millionen mal.
Auch hier kann man prüfen ob der Test überhaupt funktioniert, indem man z.B. release + acquire durch relaxed ersetzt. Geht allerdings nicht mit x86, weil x86 "total store order" macht, d.h. jeder normale Lesevorgang hat acquire Semantik und jeder normale Schreibvorgang hat immer release Semantik.
Du kannst dir auch die Test-Suite von Boost.Atomic, libstdc++ oder libc++ ansehen. Da findest do solche und weitere Tests, z.B. auch welche die die erweiterten Garantien von memory order seq_cst testen.
-
@hustbaer Danke für eine sinnvolle Antwort.