2016-03-22 14 views
1

Ich versuche, eine __int16 Array als __m128i Element darzustellen. Casting __m128i Element zu __int16 Array funktioniert gut. Mein Beispielcode:Wie Integer-Array in SIMD-Vektor umwandeln

void example() { 
    __m128i v = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); 
    __int16 *p_i = (__int16 *)&v; 
    for (int i = 0; i < 8; i++) 
     std::cout <<p_i[i] << " "; // 8 7 6 5 4 3 2 1 
    std::cout << "\n"; 

    __int16 i2[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 
    __m128i *p_v2 = (__m128i *) i2; 
    std::cout << __m128i_toString<__int16>(p_v2[0])<< "\n"; //error here 
} 

__m128i_toString<>() von this

Was habe ich verpasst?

+0

Welchen Fehler bekommen Sie? Es funktioniert gut für mich (nachdem ich "__int16" zu "int16_t" ändere und die notwendigen # # include's hinzufüge). –

+0

Es ist Laufzeitfehler. "unbehandelte Ausnahme bei '0x000488d9' in IntelHi.exe: 0xC000005: Zugriffsverletzung beim Lesen '0xfffffff'" –

+3

Oh - wahrscheinlich nur Ausrichtung dann - versuchen Sie, Ihre Daten auszurichten - fügen Sie '__attribute __ ((aligned (16)))' zu Ihrem ' __int16' Array-Deklaration. –

Antwort

3

in C++ 11, Sie alignas(16) int16_t i2[8] = ... verwenden können 16B-Ausrichtung in eine tragbaren Weise ohne Compiler-spezifische Erweiterungen wie __attribute__((aligned(16))) oder __declspec(align(16)) zu bekommen.

Siehe the code on godbolt compiled with alignas.

Beachten Sie, dass Sie generell Aliasing __m128i mit kurzen Integer-Arrays der gleichen Länge vermeiden sollten. Wenn Daten auf diese Weise in Vektoren importiert werden, kommt es zu Staus bei fehlgeschlagener Weiterleitung des Speichers. Ausführen horizontaler Operationen durch Speichern in einem Array und anschließende Verarbeitung mit Skalarkode sucks compared to SIMD.

Die Verwendung von _mm_set_epi16() wird wahrscheinlich zu besserem Code führen, da der Compiler die eigentlichen Array- und Zeigeroperationen nicht optimieren muss. In diesem Fall war es in der Lage zu tun (clang tut nur eine movaps von einer schreibgeschützten Konstante, ohne zuerst zu einem Array zu speichern). Wenn der Initialisierer keine Kompilierzeitkonstante war, werden Sie möglicherweise keine so guten Ergebnisse erhalten.