Позвольте мне предвосхитить это с ... У меня крайне ограниченный опыт работы с ASM и еще меньше с SIMD.
Но бывает, что у меня есть следующий оптимизированный код MMX / SSE, который я хотел бы перенести в инструкции AltiVec для использования на процессорах PPC / Cell.
Это, вероятно, большой вопрос ... Хотя это всего лишь несколько строк кода, у меня не было никаких проблем, пытаясь понять, что здесь происходит.
Оригинальная функция:
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;
}