2017-11-26 12 views
2

配列ベースのコードを並列化するために、インテル®AVXイントリンシクス関数を使用して大規模配列を並列処理する方法を解明しようとしています。インテル®AVXインテル®Cコンパイラ_mm256_load_si256の整数演算

私は、256ビットのAVXベクトルが最大8並列32ビット整数/ 32ビット浮動小数点数または最大4並列64ビット倍精度をサポートすることを読みました。フロート部は私に何の問題を与えていないと正常に動作しますが、整数AVX機能は私に頭痛を与えているが、私は証明するために、次のコードを使用してみましょう:

コマンドラインオプション -mavxはと組み合わせて使用​​されて

AVX準拠のIntelプロセッサ。私はAVX2の機能を使用しません。コンパイルはUbuntu 16.04でGNU99 Cを使って行います。

AVX FP:

#include <stdio.h> 
#include <stdlib.h> 
#include <immintrin.h> 

int main() 
{ 
    float data[8] = {1.f,2.f,3.f,4.f,5.f,6.f,7.f,8.f}; 
    __m256 points = _mm256_loadu_ps(&data[0]); 

    for(int i = 0; i < 8; i++) 
     printf("%f\n",points[i]); 

    return 0; 
} 

出力:

1.000000 
2.000000 
3.000000 
4.000000 
5.000000 
6.000000 
7.000000 
8.000000 

これは正確にそれがあるべきよう整数ロードAVX機能を使用する場合、しかし、これは当てはまらない。

AVX INT:

#include <stdio.h> 
#include <stdlib.h> 
#include <immintrin.h> 

int main() 
{ 
    int data[8] = {1,2,3,4,5,6,7,8}; 
    __m256i points = _mm256_loadu_si256((__m256i *)&data[0]); 

    for(int i = 0; i < 8; i++) 
     printf("%d\n",points[i]); 

    return 0; 
} 

出力:あなたは負荷のみだけ、第1〜第3、第5、第7要素は からロードされた__m256i型変数に4つの要素を生成見ることができるように

1 
3 
5 
7 
1048576 [ out of bounds ] 
0 [ out of bounds ] 
1 [ out of bounds ] 
3 [ out of bounds ] 

元の配列。 4番目の要素を越えて、参照は範囲外になります。

データセット全体を、AVX浮動小数点データ型のように整数AVXデータ型に順番にロードすると、どのようにして目的の結果が得られますか?

答えて

6

ベクトルを[]にインデックス付けするには、GNU C拡張を使用していますが、配列に戻すことはできません。 Intrinsicsに関するインテルのドキュメントにはこれについて何も言及しておらず、すべてのコンパイラがサポートしているわけではありません(MSVCなど)。

GCCは__m256iGNU C native vector of long longと定義しています。 <immintrin.h>は、intまたはshortのSIMDベクトルに異なる__m256iタイプを定義しておらず、__m256iは、それがどこから来たか/どのように設定されたかについては何も覚えていません。あなたはv8siあなたのようなtypedefネイティブのベクトル型は、(見ることができます

を(あなたがpsベクター上shufpdまたはunpcklpdを使用したい場合は、__m128d _mm_castps_pd(__m128)に持っているので、FPベクトルのためとは異なりpspdのための独立したCタイプは、存在する場合) gccドキュメントへの前のリンク)、Vec8i(8はint)、Vec32uc(32 unsigned char)のようなタイプのライブラリlike Agner Fog's VCLを使用してください。それらには演算子のオーバーロードがあり、タイプによっては_mm256_add_epi32(a, b)または_mm256_add_epi8(a,b)の代わりにa + bと書くことができます。または_mm_extract_epi32/epi8/epi16/epi64の代わりに[]を使用してください。


変数インテル固有のSIMDの要素アウト/印刷をループにポータブルかつ安全な/正しい方法をprint a __m128i variableを参照してください。 TL:DR:_mm_store/_mm256_storeをtmp配列に追加し、そのインデックスを付けます。移植性があり、整数の場合はpextrd、FPの場合はシャッフルに最適化されます。単純なケースでは実際のストア/リロードはありません。

関連する問題