私はこれを序文にしています。私はASMでの経験は非常に限られており、SIMDでの経験は非常に限られています。AltiVecへのMMX/SSE命令の移植
しかし、PPC/Cellプロセッサで使用するAltiVec命令に移植したいと思う次のMMX/SSE最適化コードがあります。
これはおそらく大きな質問です。ほんの数行のコードであっても、ここで何が起こっているのか分かりません。
本来の機能:
static inline int convolve(const short *a, const short *b, int n)
{
int out = 0;
union {
__m64 m64;
int i32[2];
} tmp;
tmp.i32[0] = 0;
tmp.i32[1] = 0;
while (n >= 4) {
tmp.m64 = _mm_add_pi32(tmp.m64,
_mm_madd_pi16(*((__m64 *)a),
*((__m64 *)b)));
a += 4;
b += 4;
n -= 4;
}
out = tmp.i32[0] + tmp.i32[1];
_mm_empty();
while (n --)
out += (*(a++)) * (*(b++));
return out;
}
私はこれを書き換える可能性がある方法上の任意のヒントは、AltiVecの命令を使用するには?
私の最初の試み(非常に間違った試み)は、このように見えます。しかし、完全に(または遠隔で)正しくはありません。
static inline int convolve_altivec(const short *a, const short *b, int n)
{
int out = 0;
union {
vector unsigned int m128;
int i64[2];
} tmp;
vector unsigned int zero = {0, 0, 0, 0};
tmp.i64[0] = 0;
tmp.i64[1] = 0;
while (n >= 8) {
tmp.m128 = vec_add(tmp.m128,
vec_msum(*((vector unsigned short *)a),
*((vector unsigned short *)b), zero));
a += 8;
b += 8;
n -= 8;
}
out = tmp.i64[0] + tmp.i64[1];
#endif
while (n --)
out += (*(a++)) * (*(b++));
return out;
}
ブリリアント。ありがとうポール。私は 'ゼロ'配列のベクトル型をsigned int型(m128変数のものと一致する)に変更する必要がありましたが、それ以外の場合は絶対的な扱いをしていました。これにより、SIMD拡張機能についてもっと学びたいと思うようになります。 –
@Tim Kane:素晴らしい - それはあなたのためにうれしい。ゼロベクトル上にはっきりと現れました - 今修正されました。 AltiVecは本当にクールですが、残念ながら今のところ出ています。 IntelのAVXやAMDのSSE5など、地平線には刺激的なSIMDがあります。 –