Der Draft-Standard C11 n1570 scheint zu bestätigen, dass dies sicher ist, aber ich behaupte, dass es unweise ist.
Ich stütze mein Argument auf die Tatsache, dass sich die Elemente eines Arrays im Speicher nicht überschneiden können, und auf die folgenden Klauseln des C11-Entwurfsstandards.
5.1.2.4 Multi-Thread-Ausführungen und Datenrennen
4. Zwei Ausdruckauswertungen Konflikt , wenn einer von ihnen einen Speicherort ändert und der andere den gleichen Speicherort liest oder ändert.
25. Die Ausführung eines Programms enthält eine Datenrasse , wenn sie zwei widersprüchliche Aktionen in verschiedenen Threads enthält, von denen mindestens einer nicht atomar ist und keiner vor dem anderen auftritt. Ein solches Datenrennen führt zu undefiniertem Verhalten.
27. ANMERKUNG 13 Compiler-Transformationen, die Zuweisungen zu einem möglicherweise gemeinsam genutzten Speicherbereich einführen, der nicht von der abstrakten Maschine geändert wird, werden von diesem Standard im Allgemeinen ausgeschlossen, da eine solche Zuweisung in Fällen, in denen eine abstrakte Maschinenausführung erfolgen würde, eine andere Zuweisung durch einen anderen Thread überschreiben würde Ich habe noch kein Datenrennen erlebt. Dies umfasst Implementierungen von Datenelementzuweisungen, die benachbarte Elemente in separaten Speicherorten überschreiben. Wir schließen im Allgemeinen auch das Umordnen von atomaren Ladungen in Fällen aus, in denen die betreffenden Atome einen Aliasnamen annehmen können, da dies die Regeln der "sichtbaren Sequenz" verletzen könnte.
28. HINWEIS 14 Transformationen, die ein spekulatives Lesen eines möglicherweise gemeinsam genutzten Speicherorts einleiten, behalten möglicherweise nicht die in diesem Standard definierte Semantik des Programms bei, da sie möglicherweise ein Datenrennen einleiten. Sie sind jedoch in der Regel im Kontext eines optimierenden Compilers gültig, der auf eine bestimmte Maschine mit wohldefinierter Semantik für Datenrennen abzielt. Sie wären für eine hypothetische Maschine ungültig, die keine Rennen toleriert oder Hardware-Race-Erkennung bietet.
Wir erfahren hier, dass es für zwei Threads UB ist, widersprüchliche Aktionen am gleichen Speicherort auszuführen, aber dass der Compiler "generell ausgeschlossen" ist, Zuweisungen zu "potentiell gemeinsam genutzten" Speicherorten einzuführen, die die abstrakte Maschine nicht ausgeführt hätte .
Sie bestätigen, dass Ihre Threads nur auf die Elemente mit ihrem eigenen Index zugreifen (lesen und schreiben). Da es keine Frage gibt, dass sie nicht auf den gleichen Speicherort zugreifen, scheint mir das, was Sie tun, sicher zu sein, vorausgesetzt, Sie erfüllen alle anderen Einschränkungen, wie die korrekte Ausrichtung Ihrer float
Variablen.
Allerdings stelle ich die Weisheit in Frage, wie Sie vorgehen. Da diese beiden Speicherorte zusammenhängend sind, werden Sie wahrscheinlich ein schwerwiegendes falsches Teilen -Problem erleben. Dies liegt daran, dass CPUs im Allgemeinen Speicher in "Zeilen" von ungefähr 32 oder 64 zusammenhängenden Bytes zwischenspeichern und den Cache-Status unter Verwendung des MESI-Protokolls kommunizieren.
Wenn ein Thread, der auf einem Kern ausgeführt wird, irgendwo innerhalb dieser Cachezeile eine -Wartung ausführt, dann sind alle Kopien der Cachezeile und alles, was darin enthalten ist, in anderen -Kernen
True sharing tritt auf, wenn die betroffenen Threads alle auf denselben Teil der Cache-Line zugreifen, da diese Ungültigkeit dann gerechtfertigt wurde, um zu verhindern, dass die kommunizierenden Threads veraltete Daten verwenden.
Auf der anderen Seite tritt false sharing auf, wenn die Threads alle auf verschiedene Teile derselben Cache-Line zugreifen. In diesem Fall war eine Ungültigmachung nicht notwendig, aber die Hardware tat es trotzdem wegen der Nähe der Zugriffe zueinander und bestrafte alle von ihnen.
Tags und Links c multithreading