2016-03-31 4 views
1

Diese Anweisung ist Teil eines Baugruppenausgangs eines C-Programms (gcc -O2). Nach dem Ergebnis verstehe ich, dass ymm6source operand 1 ist, dass alles, um ymm9 kloniert und dann xmm1 kloniert in die ymm6[127-256] ich Intel manual lesen, aber es nutzt Syntax Intel Assembly nicht in dem & t und ich will nicht Intel-Syntax verwenden . Also ymm8, ymm2 und ymm6 hier ist SRC1. Ist das wahr?Warum gcc kompilieren _mm256_permute2f128_ps zu Vinsertf128 Anweisung?

vshufps  $68, %ymm0, %ymm8, %ymm6 
vshufps  $68, %ymm4, %ymm2, %ymm1 
Vinsertf128 $1, %xmm1, %ymm6, %ymm9 

Und die wichtigste Frage ist, warum gcc die Anweisung

row0 = _mm256_permute2f128_ps(__tt0, __tt4, 0x20);

zu

Vinsertf128 $1, %xmm1, %ymm6, %ymm9 

und

row4 = _mm256_permute2f128_ps(__tt0, __tt4, 0x31); 
geändert

zu

Vperm2f128 $49, %ymm1, %ymm6, %ymm1 

Wie kann ich diese Optimierung ignorieren? Ich habe versucht -O0 aber funktioniert nicht.

Antwort

1

Die Überprüfung der Anweisungen, die im Anweisungsanalysebericht an Port 5 binden, zeigt, dass die Anweisungen broadcasts und vpermilps waren. Die broadcasts ausführen kann nur auf Port 5, sondern mit 128-bit Lasten gefolgt von vinsertf128 Anweisungen ersetzt reduziert den Druck auf Port 5 weil vinsertf128 auf Port 0 von IACA user guid

ausführen kann
4

Also ymm8, ymm2 und ymm6 hier ist SRC1. Ist das wahr?

Ja, der mittlere Operand ist immer src1 in einer 3-Operanden-Anweisung in beiden Syntaxen.

  • AT & T: op %src2, %src1, %dest
  • Intel: op dest, src1, src2

Ich will nicht Intel Syntax

Tough verwenden. Die einzige wirklich gute Dokumentation, die ich für genau weiß, was jede Anweisung tut, ist das Handbuch von Intel insn ref. Ich dachte früher AT & T-Syntax war besser, weil die $ und% Dekoratoren Mehrdeutigkeit entfernen. Ich mag das, aber ansonsten bevorzugen Sie jetzt die Intel-Syntax. Die Regeln für jedes sind einfach genug, dass Sie leicht geistig umwandeln oder "denken" können, in welchem ​​auch immer Sie ATM lesen.

Wenn Sie nicht gerade GNU C inline asm schreiben, können Sie einfach gcc -masm=intel und objdump -Mintel verwenden, um GNU-aromatisierte ASM mit Intel Mnemonics, Operandenreihenfolge und so weiter zu erhalten. Die Assembler-Anweisungen sind immer noch gas Stil, nicht NASM. Verwenden Sie http://gcc.godbolt.org/ mit nur in den wesentlichen Etiketten schön formatierte asm-Ausgang für den Code zu bekommen links.


gcc und klirren beide haben ein gewisses Verständnis von dem, was die Spezifika tatsächlich tun, so intern übersetzen sie die intrinsische zu einem gewissen Datenbewegung . Wenn es Zeit ist, Code zu senden, sehen sie, dass diese Datenbewegung mit vinsertf128 getan werden kann, so dass sie das ausstrahlen.

Auf einigen CPUs (Intel SnB-Familie) haben beide Anweisungen die gleiche Leistung, aber auf AMD Bulldozer-Familie (die nur 128b ALUs hat), vinsertf128 ist viel schneller als vperm2f128. (Quelle: siehe Agner Fogs Führer und andere Links im Tag-Wiki). Sie benötigen beide 6 Bytes zum Kodieren, einschließlich der unmittelbaren, also gibt es keinen Unterschied in der Kodegröße. vinsertf128 ist immer eine bessere Wahl als vperm2f128, die identische Datenbewegung ausführt.

gcc und clang haben keine "wörtliche Übersetzung von intrinsic in Anweisungen" Modus, weil es zusätzliche Arbeit zu implementieren erfordern würde. Wenn Sie genau wissen, welche Anweisungen der Compiler verwendet, ist Inline-Asm dafür da.

Keep in mind that -O0 doesn't mean "no optimization". Es muss immer noch durch ein paar interne Repräsentationen transformiert werden, bevor asm emittiert wird.