내가 이것에 머리말을 붙이겠습니다. 나는 ASM에 대한 경험이 극히 제한되어 있으며, SIMD에 대한 경험은 매우 적습니다.AltiVec에 MMX/SSE 명령어 포팅하기
그러나 나는 다음과 같은 MMX/SSE 내가 PPC/셀 프로세서에서 사용하기 위해 알티 벡 지침에서 포트에 싶으면, 최적화 된 코드를 가지고 발생합니다.
이것은 아마 큰 ..이 코드 몇 줄을 비록, 내가 여기에 무슨 일이 해결하려고 노력 문제의 끝이 없었습니다 부탁드립니다.
원래 기능 :
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;
}
나는이를 다시 작성하는 방법에 대한 모든 팁은 알티 벡 지침을 사용할 수 있나요?
내 첫 번째 시도 (매우 잘못된 시도는) 다음과 같이 보입니다 .. 그러나 그것은 완전히 (또는 원격으로) 올바른 아니에요.
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;
}
브릴리언트. 폴 고마워. 나는 'zero'배열의 벡터 타입을 signed int 타입 (m128 변수의 그것과 일치하도록)으로 수정해야만했다. 그렇지 않으면 절대적인 처리 (그리고 성능 측면에서의 논란)를 해왔다. 이것은 나를 SIMD 확장에 대해 더 알고 싶습니다. –
@Tim Kane : 대단하다. 다행이다. 이제 제로 벡터에 얼핏보기에 - 지금 고쳤습니다. AltiVec은 정말 멋지지만, 안타깝게도 지금은 나가고 있습니다. 예를 들어 Intel의 AVX와 AMD의 SSE5와 같이 흥미 진진한 SIMD가 있습니다. –