我试图改进一些代码,但我不能,所以我在这里寻求帮助,我也试过内在函数,但是如果你想使用内在的你需要使用GCC编译器,这个编译器编译速度慢的代码比LLVM,所有代码都变慢,所以最好的选择是直接使用asm。 我把我想要改进的两个函数,以及霓虹灯中的代码,代码返回无意义的数字。 我真的需要帮助,任何指向正确方向的点都可以帮助我。
我想改进的代码:
inline unsigned des(const unsigned char* v0)
{
unsigned r;
r = v0[0]*v0[0];
r += v0[1]*v0[1];
r += v0[2]*v0[2];
r += v0[3]*v0[3];
r += v0[4]*v0[4];
r += v0[5]*v0[5];
r += v0[6]*v0[6];
r += v0[7]*v0[7];
return r;
}
inline unsigned suma(const unsigned char* v0)
{
unsigned r;
r = v0[0];
r += v0[1];
r += v0[2];
r += v0[3];
r += v0[4];
r += v0[5];
r += v0[6];
r += v0[7];
return r;
}
霓虹灯代码无效
unsigned desneon(unsigned v0[8])
{
asm volatile (
"vld1.32 {d2- d5}, [%0] \n\t"
"vld1.32 {d6- d9}, [%0] \n\t"
"vmul.s32 d0, d2, d6 \n\t" //d0= d2*d6
"vmla.s32 d0, d3, d7 \n\t" //d0 = d0 + d3*d7
"vmla.s32 d0, d4, d8 \n\t" //d0 = d0 + d4*d8
"vmla.s32 d0, d5, d9 \n\t" //d0 = d0 + d5*d9
"vpadd.s32 d0, d0 \n\t" //d0 = d[0] + d[1]
:: "r"(v0) :
);
}
非常感谢!!!
答案 0 :(得分:2)
您需要实际返回该值。我想你想要这样的东西:
unsigned desneon(unsigned v0[8])
{
unsigned outlo;
__asm__ volatile (
"vld1.32 {d2- d5}, [%1] \n\t"
"vld1.32 {d6- d9}, [%1] \n\t"
"vmul.s32 d0, d2, d6 \n\t" //d0= d2*d6
"vmla.s32 d0, d3, d7 \n\t" //d0 = d0 + d3*d7
"vmla.s32 d0, d4, d8 \n\t" //d0 = d0 + d4*d8
"vmla.s32 d0, d5, d9 \n\t" //d0 = d0 + d5*d9
"vpadd.s32 d0, d0 \n\t" //d0 = d[0] + d[1]
"vmov %0, r4, d0 \n\t"
:"=r"(outlo)
:"r"(v0)
:"d0", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "r4"
);
return outlo;
}
我查了一下,似乎给了我正确的结果。正如@Nyx0uf所说,你可能想看看Accelerate框架 - 它有很多有用的东西可以用标准方法调用而不是用手写NEON。
答案 1 :(得分:0)
假设32位输入数据,我建议:
unsigned desneon(unsigned v0[8])
{
asm volatile (
"vldmia {q0-q1}, [%0] \n\t"
"vmul.u32 q0, q0, q0 \n\t"
"vmla.u32 q0, q1, q1 \n\t"
"vpaddl.u32 q0, q0 \n\t"
"vadd.u64 d0, d0, d1 \n\t"
"vmov r0, s0 \n\t"
:: "r"(v0) :
);
}
虽然看起来非常简短且看起来很优化,但这款霓虹灯版本的速度不会太快(甚至更慢),因为:
我建议你在这种情况下坚持使用原始的C代码。