2009-10-04 14 views
20

Ist es eine gute Idee, den Code zu vektorisieren? Was sind gute Praktiken in Bezug darauf, wann es zu tun ist? Was passiert darunter?Was bedeutet Vektorisierung?

+4

Siehe auch: http://stackoverflow.com/questions/1422149/what-is-vectorization/ –

Antwort

35

Vektorisierung bedeutet, dass der Compiler erkennt, dass Ihre unabhängigen Anweisungen als eine SIMD-Anweisung ausgeführt werden können. Übliche Beispiel dafür ist, dass, wenn Sie so etwas wie

for(i=0; i<N; i++){ 
    a[i] = a[i] + b[i]; 
} 

tun es als (unter Verwendung von Vektorschreibweise) vektorisiert werden

for (i=0; i<(N-N%VF); i+=VF){ 
    a[i:i+VF] = a[i:i+VF] + b[i:i+VF]; 
} 

Grundsätzlich ist der Compiler nimmt eine Operation, die auf VF Elemente des Arrays durchgeführt werden können die gleiche Zeit und macht diese N/VF Zeiten anstatt die Einzeloperation N mal zu machen.

Es erhöht die Leistung, aber setzt mehr Anforderungen an die Architektur.

+3

Gibt es also etwas, was ein Programmierer tun kann, um die Vektorisierung sicherzustellen (abgesehen von der Aktivierung der Optimierung)? – Jacob

+1

Soweit ich weiß, Compiler sind in Auto-Vektorisierung beschränkt, so ist Ihre beste Wette, um Ihren Code so trivial wie es sein kann. Sie können auch den erzeugten Assembly-Code prüfen, um zu sehen, ob der Compiler vektorisiert ist oder nicht. – Zed

+1

@Jacob: Sie können es nicht wirklich "sicherstellen", Sie können sich http://openmp.org/ ansehen, um dem Compiler explizit zu erklären, dass er vektorisieren soll. –

3

Es ist SSE-Code Generation.

Sie haben eine Schleife mit Float-Matrix-Code in Matrix1 [i] [j] + Matrix2 [i] [j] und der Compiler erzeugt SSE-Code.

+1

SEE ist nicht der einzige Vektorbefehlssatz. PPC hat Altivec und andere Architekturen haben ihre eigenen Vektor-Anweisungen. – Amok

11

Wie oben erwähnt, verwendet wird Vektorisierung Verwendung von SIMD-Befehlen zu machen, die in große Register gepackte identische Operationen verschiedenen Daten durchführen können.

Eine allgemeine Richtlinie, die es einem Compiler ermöglicht, eine Schleife automatisch zu bestimmen, besteht darin, sicherzustellen, dass keine s/w-Datenelemente in verschiedenen Iterationen einer Schleife fließen.

http://en.wikipedia.org/wiki/Data_dependency

Einige Compiler wie der Intel C++/Fortran Compiler sind von autovectorizing Code fähig ist. Falls es nicht möglich war, eine Schleife zu vektorisieren, kann der Intel-Compiler mitteilen, warum dies nicht möglich war. Es berichtet verwendet werden können, um den Code zu modifizieren, dass es vektorisierbare wird (vorausgesetzt, es möglich ist)

Abhängigkeiten in die Tiefe fallen, sind in dem Buch ‚optimierende Compiler für moderne Architekturen: eine Abhängigkeit basierten Ansatz‘

3

Vektorisierung Notwendigkeit nicht auf ein einzelnes Register beschränkt, das große Daten speichern kann. Zum Beispiel das '128' Bit Register, um '4 x 32' Bit Daten zu speichern. Es hängt von architektonischen Einschränkungen ab. Einige Architekturen haben unterschiedliche Ausführungseinheiten, die eigene Register besitzen. In diesem Fall kann ein Teil der Daten dieser Ausführungseinheit zugeführt werden, und das Ergebnis kann aus einem dieser Ausführungseinheit entsprechenden Register entnommen werden.

Betrachten Sie zum Beispiel den folgenden Fall.

for (i = 0; i < N; i ++) {

a [i] = a [i] + B [i];
}



Wenn ich auf einer Architektur arbeite, die zwei Ausführungseinheiten hat, dann meine Vektorgröße als zwei definiert ist. Die Schleife, die oben erwähnt wird als

für umformuliert werden (i = 0; i < (N/2); i + = 2)
{
a [i] = A [i] + B [i ];


a [i + 1] = a [i + 1] + b [i + 1];
}

HINWEIS: Die 2 innerhalb der für die Anweisung ist von der Vektorgröße abgeleitet.

Da ich zwei Ausführungseinheiten habe, werden die beiden Anweisungen innerhalb der Schleife in die beiden Ausführungseinheiten eingegeben. Die Summe wird in den Ausführungseinheiten separat gesammelt. Schließlich wird die Summe der akkumulierten Werte (von zwei Ausführungseinheiten) ausgeführt.

Die guten Praktiken sind
1. Die Einschränkungen wie Abhängigkeit (zwischen verschiedenen Iterationen der Schleife) muss vor der Vektorisierung der Schleife überprüft werden.
2. Funktionsaufrufe müssen verhindert werden.
3. Zeiger Zugriff kann Alias ​​erstellen und es muss verhindert werden.