2016-05-12 15 views
0

ein Codefragment Betrachten sie dies mit Intel SSE intrinsics wie:Ausrichtungsanforderungen, wenn das Ergebnis der SSE-Operationen zu speichern

void foo(double* in1ptr, double* in2ptr) 
{ 
    double result[8]; 

    /* .. stuff .. */ 

    __m128d in1 = _mm_loadu_pd(in1ptr); 
    __m128d in2 = _mm_loadu_pd(in2ptr); 
    __m128d* resptr = (__m128d*)(&result[4]); <---------- 
    *resptr = __mm_add_pd(in1,in2); 

    /* .. stuff .. */ 
} 

in der angegebenen Linie - wenn resptr erklärt zu dem Ort bei Index Punkt 4 innerhalb Ergebnis-Array -

1) Dies funktioniert in gcc, aber ist dies der richtige Weg, Dinge zu tun?

2) Was sind die Erwartungen an die Ausrichtung, kann ich den Zeiger resptr so erstellen, dass er auf einen beliebigen Speicherort zeigt und anschließend das Ergebnis einer SSE-Operation an diesem Speicherort speichert?

Antwort

1

laden/speichern intrinsics existieren, um dem Compiler Alignmentgarantien oder deren Fehlen zu kommunizieren. Wenn Ihre Daten 16B-ausgerichtet oder 32B-ausgerichtet sind, benötigen Sie sie nicht.

Nur Casting zu (__m128d*) folgt der üblichen C-Semantik von impliziert, dass die __m128d ausreichende Ausrichtung hat. (Compiler verwenden movapd anstelle von movupd und werden zur Laufzeit einen Fehler verursachen, wenn die Adresse nicht ausgerichtet ist).

In diesem Fall haben Sie nichts unternommen, um die Ausrichtung sicherzustellen. Es ist nur ein Zufall, dass Ihr lokales Array 16B-ausgerichtet ist. Wenn Sie alignas(16) double result[8]; verwenden, ist dieser Code sicher.

Verwenden Sie für nicht ausgerichtete Speicher _mm_storeu_pd. Siehe auch das Tag-Wiki.