2015-06-09 17 views
5

Ich frage mich, ob es einen Compiler (gcc, xlc, etc.) auf Power8, die OpenMP SIMD Konstrukte auf Power8 unterstützt? Ich habe versucht mit XL (13.1), aber ich konnte nicht erfolgreich kompilieren. Wahrscheinlich unterstützt es noch nicht simd construct.OpenMP SIMD on Power8

Ich könnte mit gcc 4.9.1 kompilieren (mit diesen Flags -fopenmp -fopenmp-simd und -O1). Ich lege Unterschiede zwischen 2 Asm-Dateien.

Kann ich sagen, dass gcc 4.9 in der Lage ist, altivec-Code zu generieren? Um mehr zu optimieren, was soll ich tun? (Ich habe versucht, mit -O3, beschränken Behandlung)

Mein Code ist sehr einfach:

int *x, *y, *z; 
x = (int*) malloc(n * sizeof(int)); 
y = (int*) malloc(n * sizeof(int)); 
z = (int*) malloc(n * sizeof(int)); 

#pragma omp simd 
for(i = 0; i < N; ++i) 
    z[i] = a * x[i] + y[i]; 

Und generierte Assembly hier ist

.L7: 
    lwz 9,124(31) 
    extsw 9,9 
    std 9,104(31) 
    lfd 0,104(31) 
    stfd 0,104(31) 
    ld 8,104(31) 
    sldi 9,8,2 
    ld 10,152(31) 
    add 9,10,9 
    lwz 10,124(31) 
    extsw 10,10 
    std 10,104(31) 
    lfd 0,104(31) 
    stfd 0,104(31) 
    ld 7,104(31) 
    sldi 10,7,2 
    ld 8,136(31) 
    add 10,8,10 
    lwz 10,0(10) 
    extsw 10,10 
    lwz 8,132(31) 
    mullw 10,8,10 
    extsw 8,10 
    lwz 10,124(31) 
    extsw 10,10 
    std 10,104(31) 
    lfd 0,104(31) 
    stfd 0,104(31) 
    ld 7,104(31) 
    sldi 10,7,2 
    ld 7,144(31) 
    add 10,7,10 
    lwz 10,0(10) 
    extsw 10,10 
    add 10,8,10 
    extsw 10,10 
    stw 10,0(9) 
    lwz 9,124(31) 
    addi 9,9,1 
    stw 9,124(31) 

GCC mit -O1 -fopenmp-simd

.L7: 
lwz 9,108(31) 
mtvsrwa 0,9 
mfvsrd 8,0 
sldi 9,8,2 
ld 10,136(31) 
add 9,10,9 
lwz 10,108(31) 
mtvsrwa 0,10 
mfvsrd 7,0 
sldi 10,7,2 
ld 8,120(31) 
add 10,8,10 
lwz 10,0(10) 
extsw 10,10 
lwz 8,116(31) 
mullw 10,8,10 
extsw 8,10 
lwz 10,108(31) 
mtvsrwa 0,10 
mfvsrd 7,0 
sldi 10,7,2 
ld 7,128(31) 
add 10,7,10 
lwz 10,0(10) 
extsw 10,10 
add 10,8,10 
extsw 10,10 
stw 10,0(9) 
lwz 9,108(31) 
addi 9,9,1 
stw 9,108(31) 

Um um Details zu klären und zu verstehen, habe ich noch eine Anwendung n das ist n^2 nBody-Anwendung. Diesmal steht meine Frage im Zusammenhang mit diesen Compilern (gcc 4.9 und XL 13.1) und Architekturen (Intel und Power).

Ich habe alle Codes in Kern https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-input-c (Vollversion von Eingabecode input.c)

  1. Power8 & XLC - Es sagt „nicht vektorisiert wurde SIMD weil es Funktionsaufrufe enthält. (Es gibt sqrtf) ". Es ist vernünftig. Aber in der Asm-Code kann ich sehen, xsnmsubmdp ist es normal? (die assembly: https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-xlc-noinnersimd-asm)
  2. Power8 & gcc ich versuchte, es in 2 Möglichkeiten zu kompilieren (mit OMP SIMD-Konstrukt und ohne). Es hat meinen asm-Code geändert, ist das normal? (Nach OpenMP, sollte der Code nicht Funktionsaufruf enthält) (Assembilies: https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-gcc-noinnersimd-asm & https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-power8-gcc-innersimd-asm)
  3. i74820K & gcc Ich habe einen gleichen Test mit omp SIMD und ohne sie. Die Ausgabecodes sind ebenfalls unterschiedlich. Führt FMA diesen Codeblock aus? (Assembilies: https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-i74820k-gcc-noinnersimd-asm & https://gist.github.com/grypp/8b9f0f0f98af78f4223e#file-i74820k-gcc-innersimd-asm)

Vielen Dank im Voraus

+2

Das OpenMP 'simd'-Konstrukt ist Teil von OpenMP 4.0 und wird daher von GCC 4.9 und höher unterstützt. XL C 13.1.0 bietet teilweise Unterstützung. –

+0

@HristoIliev danke für die schnelle Antwort. Ich stelle mehr Details in Frage. – grypp

+0

Sorry, ich verstehe Power ISA nicht. Stellen Sie sicher, dass der Compiler darauf hingewiesen wird, dass sich 'x',' y' und 'z' nicht gegenseitig aliasieren können. Andernfalls könnte der Compiler den Code nicht vektorisieren. Sie könnten den Zeigern entweder die 'restrict'-Behandlung geben oder ein Compiler-spezifisches Pragma anwenden, das den Compiler anweist, dass die innerhalb der Schleife dereferenzierten Zeiger sich nicht gegenseitig aliasieren können. Möglicherweise müssen Sie auch den Compiler darauf hinweisen, dass die Speicherzuweisung vier Wort-ausgerichtet ist. –

Antwort

3

Der XL-Compiler auf POWER Linux unterstützt derzeit nur eine Teilmenge der OpenMP 4.0-Funktionen. Die SIMD-Konstrukt-Funktion wird momentan nicht unterstützt, sodass der Compiler das Konstrukt in Ihrem Quellcode nicht erkennt. Jedoch

, wenn Vektorisierung ist das, was Sie suchen dann die gute Nachricht ist, dass der XL-Compiler sollte bereits automatisch Code vektorisiert, solange Sie mindestens verwenden Sie die folgenden Optimierungsmöglichkeiten

O3 - qhot -qarch = pwr8 -qtune = pwr8

Diese Optionen high-order loop transformations zusammen mit POWER8 spezifischen Optimierungen ermöglichen, einschließlich Loop auto-Vektorisierung für Ihre Schleife.

Danach sollten Sie einige VMX & VSX-Anweisungen in dem erzeugten Assembler-Code ähnlich die folgenden sehen:

188: 19 2e 80 7c  lxvw4x vs36,0,r5 
18c: 84 09 a6 10  vslw v5,v6,v1 
190: 10 00 e7 38  addi r7,r7,16 
194: 10 00 a5 38  addi r5,r5,16 
198: 40 28 63 10  vadduhm v3,v3,v5 
19c: 80 20 63 10  vadduwm v3,v3,v4 
1a0: 19 4f 66 7c  stxvw4x vs35,r6,r9 
1a4: 14 02 86 41  beq  cr1,3b8 <foo+0x3b8> 
1a8: 10 00 20 39  li  r9,16 
1ac: 19 4e 27 7d  lxvw4x vs41,r7,r9 
1b0: 19 3e a0 7c  lxvw4x vs37,0,r7 

By the way, können Sie auch einen Optimierungsbericht aus dem XL-Compiler erhalten, indem die -qreport mit Möglichkeit. Dies wird erklären, welche Schleifen vektorisiert wurden und welche Schleifen nicht und aus welchem ​​Grund. z.B.

1586-542 (I) Schleife (loop Index 1 mit Nest-Level 0 und Iterationszähler 100) bei test.c war SIMD vektorisiert.

oder

1586-549 (I) Schleife (loop Index 2) bei nicht test.c wurde SIMD vektorisiert, weil eine Datenabhängigkeit Vektorisierung SIMD verhindert.

Hoffe, das hilft!

+0

Vielen Dank für Ihre Antwort. Ich habe eine andere Frage, die sich auf den Vektorisierungs-For-Loop-Block bezieht, wenn dieser Funktionsaufruf enthält. – grypp

+0

Vielleicht könnten Sie die Informationen über GCC von meinem Beitrag in Ihre integrieren und dann werde ich meine löschen, da es sich eher um einen erweiterten Kommentar als um eine vollständige Antwort handelte. –

3

Ich habe keinen Zugriff auf eine Power-basierte Maschine gerade jetzt, aber einige Experimente mit dem AST-Kipper auf x86 zeigt, dass GCC 4.9 0,2 startet nur SIMD-Code produzieren, sobald das Niveau der Optimierung O1 erreicht, dh die folgenden Optionen, um den Trick tun sollten:

-fopenmp-simd -O1 

das gleiche gilt für GCC 5.1 wahr ist .0.

Beachten Sie auch, dass der Vektorisierer ein Kostenmodell anwendet, das in einigen Fällen möglicherweise verhindert, dass vektorisierter Code tatsächlich erzeugt wird. Unter -fsimd-cost-model und ähnlichen Optionen here erfahren Sie, wie Sie dieses Verhalten überschreiben können.

+0

Danke, ich kompiliere und sehe Änderungen. Aber ich frage mich auch, ob es optimierten Code genug in Bezug auf altivec Operationen ist – grypp

+0

Das weiß ich nicht. Aber die Erhöhung der Optimierungsstufe sollte die Dinge noch weiter verbessern. –

+0

Ich habe dieses Problem gelöst. Aber interessanterweise konnte ich keine sehr guten Ergebnisse erzielen, denn jetzt sieht i7 besser aus. Ich denke, es liegt daran, dass SSE4 – grypp