2016-03-25 16 views
-2

Ich betrachte ein einfaches Problem - Beschleunigung der Berechnung der komponentenweise Produkt von zwei Doppelfelder. Ich habe festgestellt, dass ich mit AVX-Befehlen nur etwa 20% Beschleunigung erziele, verglichen mit der sequentiellen Multiplikation in einer Schleife.Intel intrinsics assembly code

ich beschlossen, die Latenzen für die beiden Fälle zu prüfen und wurde mit dem Assembler-Code der Ladeoperation verwirrt:

### __m256d pd; 
### pd = _mm256_load_pd(a); 
    movq  -112(%rbp), %rax //Pushing the pointer to the stack        
    vmovapd (%rax), %ymm0  //Pushing 32 bytes from memory to ymm         
    vmovapd %ymm0, -80(%rbp) //What is        
    vmovapd -80(%rbp), %ymm0 //happening here?       
    vmovapd %ymm0, -48(%rbp) //Quite slow down, since vmovapd cost ~ vmulpd       

Above Teil der Anordnung für die folgenden C-Code ist:

inline int test(double * a) { 
    __m256d pd; 
    pd = _mm256_load_pd(a); 
    return 1; 
} 

in der Beschreibung der __m256_load_pd wird gesagt, dass es auf diese Weise getan wird:

dst[255:0] := MEM[mem_addr+255:mem_addr] 
dst[MAX:256] := 0 

, d.h. in umgekehrter Reihenfolge? Aber wie haben diese 2 Zeilen Assemblercode damit zu tun?

+1

Sie kompilieren mit der Optimierung deaktiviert, so gcc macht braindead langsamen Code. Mit der Optimierung kompiliert 'test()' nur zu der 'return 1', weil' pd' nie benutzt wird. Wenn die Beschleunigung um 20% mit "-O0" ist, versuchen Sie es mit "-O3". Sie müssen die Optimierung aktivieren, wenn der Code schnell ausgeführt werden soll. –

+1

AT & T-Syntax verwendet 'op src2, src1, dest' mit'% 'Dekoratoren auf Registernamen, während Intel-Syntax' op dest, src1, src2' verwendet. Der Pseudocode des Intel-Handbuchs ist überhaupt nicht asm, er beschreibt nur die Operation. –

+0

20% Beschleunigung ist das Ergebnis für -O3 Flag mit Icpc. – Tzoiker

Antwort

0

Es ist sehr schwierig, diese Frage ohne etwas mehr Kontext, jenseits von Kompilierungsflags zu beantworten. Abhängig von der Anzahl der ausgeführten Threads und der Größe der Double-Arrays ist Ihr Problem möglicherweise speichergebunden, dh die Leistung ist durch den Speicherzugriff begrenzt.

sehr große Daten Sie wollen einen Blick auf Stream Benchmark haben. Die Verwendung von AVX-Intrinsics wird Software- und Hardware-Vorabruf sowie Datenausrichtung unterstützen, die die + 20% erklären können. Wie auch immer, Sie sind speichergebunden (Laden von Daten aus dem Systemspeicher in den L1-Cache), und das Ausführen von Operationen ist im Vergleich zu AVX-Operationen irrelevant und wird wahrscheinlich durch paralleles Laden der Daten verdeckt (dank der Magie des Prefetch).

DATEN IN L2 CACHE Je nach Anzahl der gleichzeitigen Threads können Daten mit höherer Geschwindigkeit übertragen werden. Jedoch ist die Durchführung eines Mul ts der Daten nicht komplex genug, um die Kosten für das Speicher-Marshalling zu übernehmen.

DATEN IN L1-Cache Für diesen Fall können Sie eine gewisse Verbesserung in der Leistung sehen, aber es könnte andere suprises wie Ausführungsabhängigkeit und Latenz von den L1-Cache Lasten induziert werden. Das Laden von ausgerichteten Daten in Registern mit 256 Bit ist jedoch wahrscheinlich die beste Leistung.