2015-10-07 7 views
5

Ich hatte eine Frage über die neue ausgerichtete Option in OpenMP. Dies ist im Zusammenhang mit der Verwendung mit #pragma omp simd aligned(a:n)OpenMP 4 ausgerichtete Option?

Angenommen, ich habe ein Array von ganzen Zahlen, die ich mit posix_memalign zugewiesen, so dass ich weiß, dass das Array beginnt auf sagen wir eine 32-Byte-Grenze. Sagen wir jetzt, ich möchte jeden Wert in diesem Array quadrieren. Kann ich sagen ...

int* array = { some array of length len aligned to 32 bytes }; 
#pragma omp simd aligned(array:32) 
for(int i = 0; i < len; i++) 
    array[i] *= array[i]; 

Ist das eine sichere Annahme? Oder bedeutet aligned auch, dass der Datentyp der Größe, den ich im Array verwende (int), ein Vielfaches von 32 Bytes ist? Ein bisschen wie, wie das Attribut ((ausgerichtet (32)) in gcc wird die Art der Breite mindestens 32 Bytes machen.

+0

32 Bytes -> 32 Bits –

+0

Ja, genau das ist die Ausrichtung auf 32 Bytes. – NoseKnowsAll

+1

OP bedeutet 32 ​​Bytes, vermutlich weil das die Länge von 256 Bit SIMD ist, z.B. AVX-2. – Jeff

Antwort

3

Um sicherzustellen, dass wir einander verstehen, nehmen wir an, Ihre array ist in der Tat 256bit ausgerichtet (die entspricht Ihrer 32-Byte-Ausrichtung)

Dann ist Ihr #pragma omp simd aligned(array:32) sicher, unabhängig von der Länge des Arrays oder der Größe des Array-Typs, es kommt nur auf die Adresse an, auf die verwiesen wird der "Zeiger", der verwendet wird, um das Array zu referenzieren.


EDIT: Ich erkannte, dass meine Antwort, obwohl korrekt, etwas trocken war, da ich nur antwortete, aber ohne "offizielle" Unterstützung dafür. Hier sind einige Auszüge aus dem Standard meine Antwort zu erhalten:

Von dem OpenMP 4.0 standard §2.8.1:

[C/C++: Die ausgerichtete Klausel erklärt, dass das Objekt, zu dem jeweils Listenelement Punkte ausgerichteten auf die Anzahl der Bytes, die im optionalen Parameter der ausgerichteten Klausel ausgedrückt werden.]

Der optionale Parameter der aligned-Klausel, alignment, muss ein konstanter positiver ganzzahliger Ausdruck sein. Wenn kein optionaler Parameter angegeben ist, werden implementierungsdefinierte Standardausrichtungen für SIMD Anweisungen auf den Zielplattformen angenommen.

[...]

[C: Die Art der Listenelemente in der ausgerichteten Klausel erscheinen müssen Array oder Zeiger sein.]

[C++: Die Art der Listenelemente in der ausgerichteten Klausel erscheinen müssen Array, Zeiger, Bezug auf Array, oder Verweis auf Zeiger.]

Wie Sie sehen können, gibt es keine Annahmen über den Typ der Daten, auf die die Variable innerhalb der aligned-Klausel zeigt oder auf die verwiesen wird. Die einzige Annahme ist, dass die Adresse des Speichersegments auf den optionalen Parameter oder auf einige "implementationsdefinierte Standardausrichtungen" ausgerichtet ist (was BTW ausdrücklich dazu ermutigt, diesen optionalen Parameter immer anzugeben, da ich keine Ahnung habe, was das ist Implementation-definierten Standardwert könnte sein, und mehr auf den Punkt, ob ich sicher sein werde, dass mein Array tatsächlich auf diese Weise ausgerichtet ist).

3

aligned(ptr:n) teilt dem Compiler mit, dass das Array hinter ptr mit einer Adresse beginnt, die auf n Bytes ausgerichtet ist. Dies hilft dem Compiler bei der Entscheidung, wie die Schleife optimal vektorisiert werden kann. Da viele Vektoreinheiten erfordern, dass Vektorlasten und Speicher ausgerichtet werden, muss der Compiler, wenn der Compiler die Ausrichtung der Daten zur Kompilierungszeit nicht ableiten kann, Laufzeitcode generieren, der die Ausrichtung überprüft und schließlich die nicht ausgerichteten Abschnitte der Schleife ausführt Anfang und am Ende des Iterationsraums) mit skalaren Anweisungen. Diese Prüfungen sind zeitaufwendig, insbesondere bei kleineren Array-Längen. Wenn die korrekte Ausrichtung zur Kompilierzeit bekannt ist, kann der Compiler die erforderlichen Skalaroperationen direkt ausgeben. Mit AVX-512 (Intel Xeon Phi) werden unausgerichtete Lasten und Speichervorgänge unter Verwendung von Maskierung ausgeführt, und das Bereitstellen der korrekten Ausrichtung ermöglicht es dem Compiler, die maskierten Anweisungen nach Bedarf direkt auszugeben, anstatt die Masken zur Laufzeit zu berechnen.

+0

Nicht ausgerichtete Lasten und Speicher sind seit x Nehalem (2008) kein großes Problem auf x86-Kernen. –

+0

Sie sind nicht so lang, da sie keine Cache-Zeilen-Splits verursachen, obwohl diese auf Nehalem viel billiger sind als auf früheren x86-Mikroarchitekturen. Jedenfalls ist mein Kommentar zur Codegenerierung allgemein - der Compiler kann die Ausrichtungsklausel bei einer bestimmten Architektur ignorieren. –

+0

Stellt sich heraus, Ausrichtung ist mehr als ich selbst seit Nehalem. Sie können darüber in meiner Antwort hier lesen (mit mehreren Korrekturen) http://stackoverflow.com/questions/33504003/how-to-write-c-code-that-the-compiler-can-efficiently-compile-to- sse-oder-avx/33518813 # 33518813 –