こんにちは私はAVX2組み込み関数に奇妙な問題があります。私はint64_t *キャストで_m256iベクトルへのポインタを作成します。次に、ポインタの逆参照によって値を割り当てます。奇妙なことは、ベクトル変数の後ろにいくつかのcout文を実行しない限り、値がベクトル変数には見られないということです。ポインタとベクタは同じメモリアドレスを持ち、ポインタの逆参照は正しい値を生成しますが、ベクタは正しくありません。私は何が欠けていますか?int64_t内在のAVX2へのキャストポインタ_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|
これはどのコンパイラですか?私はこれがGCCのコーナーケースの1つであると信じています。厳密なエイリアス違反が実際には起こらないかもしれないにもかかわらず実際に問題を引き起こすでしょう。 (SIMD型は '__may_alias__'と宣言されています)厳密なエイリアスを無効にしようとしましたか? '-Wstrict-aliasing'はそれを不平にしますか? – Mysticial
@Mysticial:おそらく、プログラムが未定義の振る舞いをしているので、コンパイラは変数を一貫して保つことをあきらめますか? m = 4..9では 'ptr [m]'は '__m256i R_A0to3'の外側からアクセスします。いずれにせよ、これはベクトルを使うばかげた方法です。これをしないでください。実際にバッファに格納してベクトルを変更する場合は、それを行うコードを記述し、その後にベクトルを再読み込みします。あるいは、おそらくユニオンを使用します。ポインタキャストによる型打ちは良いイディオムではありません。 –
@PeterCordes Aha、そうだよ!私はそれが限界を超えているのを見ていませんでした。 – Mysticial