質問
私は、高速指数の結果を計算するためにSIMDを使用しています。私は非SIMDコードとのタイミングを比較します。累乗は、角と乗算アルゴリズムを使用して実装されます。
普通(非SIMD)コードのバージョン
b = 1;
for (i=WPE-1; i>=0; --i){
ew = e[i];
for(j=0; j<BPW; ++j){
b = (b * b) % p;
if (ew & 0x80000000U) b = (b * a) % p;
ew <<= 1;
}
}
SIMDバージョン:
B.data[0] = B.data[1] = B.data[2] = B.data[3] = 1U;
P.data[0] = P.data[1] = P.data[2] = P.data[3] = p;
for (i=WPE-1; i>=0; --i) {
EW.data[0] = e1[i]; EW.data[1] = e2[i]; EW.data[2] = e3[i]; EW.data[3] = e4[i];
for (j=0; j<BPW;++j){
B.v *= B.v; B.v -= (B.v / P.v) * P.v;
EWV.v = _mm_srli_epi32(EW.v,31);
M.data[0] = (EWV.data[0]) ? a1 : 1U;
M.data[1] = (EWV.data[1]) ? a2 : 1U;
M.data[2] = (EWV.data[2]) ? a3 : 1U;
M.data[3] = (EWV.data[3]) ? a4 : 1U;
B.v *= M.v; B.v -= (B.v / P.v) * P.v;
EW.v = _mm_slli_epi32(EW.v,1);
}
}
それが正しく計算されても問題があり、SIMDバージョンは非SIMDバージョンよりも時間がかかってます。
私はその理由をデバッグする助けてください。コーディングSIMD上の任意の提案も歓迎されます。
感謝&よろしく、 Anupます。
解決
forループのすべての機能だけではなく2、SIMD機能する必要があります。あなたの2つの機能の引数を設定するには服用時間は少ないし、最適な(最も可能性が高いコンパイラによって最適化されている)あなたの元の例です。
他のヒント
は32ビットのintデータ用A SIMDループは、一般的に次のようになります
for (i = 0; i < N; i += 4)
{
// load input vector(s) with data at array index i..i+3
__m128 va = _mm_load_si128(&A[i]);
__m128 vb = _mm_load_si128(&B[i]);
// process vectors using SIMD instructions (i.e. no scalar code)
__m128 vc = _mm_add_epi32(va, vb);
// store result vector(s) at array index i..i+3
_mm_store_si128(&C[i], vc);
}
あなたは、あなたはおそらく、SIMD最適化から何かを得ることはありませんループ内のスカラコードとSIMDコード間を移動する必要があることが判明した場合。
SIMDプログラミングのスキルの多くは、与えられたSIMDアーキテクチャが提供するサポート命令とデータ型の数が限られているあなたのアルゴリズムを動作させるための方法を見つけることから来ています。あなたは、多くの場合、例えば、可能な限り最高のパフォーマンスを得るためにあなたのデータセットののアプリオリの知識を活用する必要があります。あなたは32ビットの整数値は、実際に16ビットに収まるが、その実装するために非常に簡単に自分のアルゴリズムの乗算一部になるだろうという範囲を持っていることを確実に知っていれば。
所属していません StackOverflow