2016-07-29 36 views
2

Ich versuche, einige der Intel Intrinsics zu testen, um zu sehen, wie sie funktionieren. So habe ich eine Funktion, die für mich zu tun, und das ist der Code:Problem mit __m256 Art von Intel intrinsics

void test_intel_256() 
{ 
__m256 res,vec1,vec2; 

__M256_MM_SET_PS(vec1, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0); 
__M256_MM_SET_PS(vec1, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0); 

__M256_MM_ADD_PS(res,vec1,vec2); 

if (res[0] ==9 && res[1] ==9 && res[2] ==9 && res[3] ==9 
    && res[4] ==9 && res[5] ==9 && res[6] ==9 && res[7] ==9) 
    printf("Addition : OK!\n"); 
else 
    printf("Addition : FAILED!\n"); 
} 

Aber dann diese Fehler ich erhalte:

error: unknown type name ‘__m256’ 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 

Was bedeutet, dass der Compiler nicht die __m256 Typ erkennt und infolgedessen kann er die Res nicht als ein Array von Schwimmern sehen. Ich bin auch diese Bibliotheken mmintrin.h, emmintrin.h, xmmintrin.h und ich bin mit Eclipse Mars

So will ich wissen, was ist, ob das Problem vom Compiler oder die Hardware oder etwas anderes? und wie kann ich es lösen? Vielen Dank!

+0

Sind Sie sicher, dass Ihre CPU AVX unterstützt? Welche CPU verwendest du? –

+0

@DanielMargosian: Selbst wenn ihre CPU AVX nicht unterstützt, sollte der Compiler sie trotzdem kompilieren können. (Kreuzkompilierung existiert). – zindorsky

+0

Meine CPU ist ** Intel® Core ™ i7-4700MQ CPU @ 2,40 GHz × 8 ** und es unterstützt ** SSE4.1/4.2, AVX 2.0 ** –

Antwort

3

MMX und SSE2 sind Basis für x86-64, aber AVX ist nicht. Sie tun müssen speziell aktivieren AVX, wo Sie nicht für SSE2.

Build mit -march=haswell oder was auch immer CPU Sie tatsächlich haben. Oder benutzen Sie einfach -mavx. Vorsicht

dass gcc -mavx mit dem Standard-tune=generic wird geteilt 256b loadu/storeu intrinsics in vmovups xmm/vinsertf128, was schlecht ist, wenn Ihre Daten tatsächlich die meiste Zeit ausgerichtet ist, und besonders schlecht auf Haswell mit begrenzten Shuffle-Port-Durchsatz.

Es ist gut für Sandybridge und Bulldozer-Familie, wenn Ihre Daten wirklich nicht ausgerichtet sind. Siehe https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568: Es betrifft sogar AVX2 Vektor-Integer-Code, obwohl alle AVX2 CPUs (außer vielleicht Excavator und Ryzen) durch dieses Tuning geschädigt werden. tune=generic berücksichtigt nicht, welche Befehlssatzerweiterung aktiviert ist, und es gibt keine tune=generic-avx2.

Sie könnten -mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store verwenden. Das ermöglicht noch immer keine anderen Optimierungsoptionen (wie das Optimieren der Makrofusion von Vergleich und Verzweigung), die alle modernen x86-CPUs haben (außer Low-Power-CPUs), aber dies wird nicht von gcc's tune = generic aktiviert. (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855).


auch:

Ich schließe diese Bibliotheken mmintrin.h, emmintrin.h, xmmintrin.h

Tu das nicht. Always just include immintrin.h in SIMD code. Es zieht alle Intel SSE/AVX-Erweiterungen ein. Aus diesem Grund Sie error: unknown type name ‘__m256’


Beachten Sie bekommen, dass Indizierung Vektortypen liegen __m256 ist Nicht-Standard und nicht tragbar. Sie sind keine Arrays, und es gibt keinen Grund, dass Sie erwarten, dass [] wie ein Array funktioniert. Das Extrahieren des 3. Elements oder etwas von einem SIMD-Vektor in einem Register erfordert einen Shuffle-Befehl, nicht einen Ladevorgang.


Wenn Sie handliche Wrapper für Vektortypen möchten Sie tun Sachen wie operator[] Gebrauch lassen Skalare aus Elementen der Vektorvariablen zu extrahieren, einen Blick auf Agner Fog Vector Class Library. Es ist GPL, also müssen Sie sich andere Wrapper-Bibliotheken anschauen, wenn das ein Problem ist.

Es lässt Sie Dinge zu tun wie

// example from the manual for operator[] 
Vec4i a(10,11,12,13); 
int b = a[2]; // b = 12 

können Sie normale intrinsics auf VCL-Typen verwenden. Vec8f ist ein transparenter Wrapper auf __m256, so dass Sie es mit _mm256_mul_ps verwenden können.

1

versuchen, diese aus

res = _MM_ADD_PS (vec1, vec2); , weil der Prototyp des __M256_MM_ADD_PS

ist __m256 _MM_ADD_PS (__ m256, __ m256);

es dauert zwei __m256 Datentypen als Parameter und gibt ihre Summe als __m256 Daten, wie

int add (int, int);

zum Initialisieren

VEC = _MM_setr_PS (7.0,7.0,7.0,7.0,7.0,7.0,7.0,7.0) oder

VEC = _MM_LOAD_PS (& FER) oder

VEC = _MM_LOAD_PS (ptr)