Hallo Ich habe ein seltsames Problem mit AVX2 intrinsics. Ich erstelle einen Zeiger auf einen _m256i Vektor mit einer int64_t * Besetzung. Ich weise dann einen Wert zu, indem ich den Zeiger dereferenziere. Das Seltsame ist, dass der Wert in der Vektorvariablen nicht beobachtet wird, es sei denn, ich führe ein paar Cout-Anweisungen danach aus. Der Zeiger und der Vektor haben die gleiche Speicheradresse, und bei der Dereferenzierung erzeugt der Zeiger den richtigen Wert, der Vektor jedoch nicht. Was vermisse ich?int64_t Zeiger auf AVX2 intrinsisch _m256i
// Vector Variable
__m256i R_A0to3 = _mm256_set1_epi32(0xFFFFFFFF);
int64_t *ptr = NULL;
for(int m=0; m<4; m++){
// Cast pointer to vector type
ptr = (int64_t*)&R_A0to3;
cout<<"ptr_ADDRESS: "<<ptr<<endl;
cout<<"&R_A0to3_ADDRESS: "<<&R_A0to3<<endl;
// access
ptr[m] = (int64_t) m_array[m];
// generic function that prints out register
print_mm256_reg<int64_t>(R_A0to3, "R_A0to3");
cout<<"m_array: "<< m_array[m]<<std::ends;
// Additional print statements
cout<<"ptr[m]: "<< ptr[m]<<std::endl;
cout<<"ptr[0]: "<< ptr[0]<<std::endl;
cout<<"ptr[1]: "<< ptr[1]<<std::endl;
cout<<"ptr[2]: "<< ptr[2]<<std::endl;
cout<<"ptr[3]: "<< ptr[3]<<std::endl;
print_mm256_reg<int64_t>(R_A0to3, "R_A0to3");
}
Output:
ptr_ADDRESS 0x7ffd9313e880
&R_A0to3_ADDRESS 0x7ffd9313e880
m_array: 8
printing reg - R_C0to3 -1| -1| -1| -1|
printing reg - R_D0to3 -1| -1| -1| -1|
Output with Additional print statements:
ptr_ADDRESS 0x7ffd36359e20
&R_A0to3_ADDRESS 0x7ffd36359e20
printing reg - R_A0to3 -1| -1| -1| -1|
m_array: 8
ptr[0]: 8
ptr[1]: -1
ptr[2]: -1
ptr[3]: -1
printing reg - R_A0to3 8| -1| -1| -1|
Welcher Compiler ist das? Ich glaube, dass dies einer der Eckfälle in GCC ist, wo eine strenge Aliasing-Verletzung tatsächlich Probleme verursachen wird, obwohl sie dies nicht tun sollten. (SIMD-Typen werden als '__may_alias__' deklariert.) Haben Sie versucht, das strikte Aliasing zu deaktivieren? Verursacht '-Wstrict-Aliasing' eine Beschwerde? – Mysticial
@Mysticial: Vielleicht gibt der Compiler auf, die Variablen kohärent zu halten, weil das Programm undefiniertes Verhalten hat? 'ptr [m]' für m = 4..9 greift außerhalb von '__m256i R_A0to3' zu. In jedem Fall ist dies eine alberne Art, Vektoren zu verwenden. Tu das nicht. Wenn Sie wirklich in einem Puffer speichern und einen Vektor ändern möchten, schreiben Sie Code, der das tut, und lädt den Vektor anschließend neu. Oder möglicherweise eine Union verwenden. Typ-Punning mit Pointer-Casts ist kein gutes Idiom. –
@PeterCordes Aha, du hast Recht! Ich habe nicht gesehen, dass es außerhalb der Grenzen ging. – Mysticial