我需要为项目编写优化的NEON代码,我非常乐意编写汇编语言,但为了便携性/可维护性,我使用的是NEON instrinsics.这段代码需要尽可能快,所以我利用我在ARM优化方面的经验来正确地交错指令并避免管道停顿.无论我做什么,GCC都会对我起作用,并且会创建更慢的代码.
有谁知道如何让GCC摆脱困境并将我的内在函数转换为代码?
这是一个例子:我有一个简单的循环来否定和复制浮点值.它一次使用4组4个,以便为内存加载和执行指令留出一些时间.剩下很多寄存器,所以它没有理由把事情搞糟.
float32x4_t f32_0, f32_1, f32_2, f32_3;
int x;
for (x=0; x<n-15; x+=16)
{
f32_0 = vld1q_f32(&s[x]);
f32_1 = vld1q_f32(&s[x+4]);
f32_2 = vld1q_f32(&s[x+8]);
f32_3 = vld1q_f32(&s[x+12]);
__builtin_prefetch(&s[x+64]);
f32_0 = vnegq_f32(f32_0);
f32_1 = vnegq_f32(f32_1);
f32_2 = vnegq_f32(f32_2);
f32_3 = vnegq_f32(f32_3);
vst1q_f32(&d[x], f32_0);
vst1q_f32(&d[x+4], f32_1);
vst1q_f32(&d[x+8], f32_2);
vst1q_f32(&d[x+12], f32_3);
}
Run Code Online (Sandbox Code Playgroud)
这是它生成的代码:
vld1.32 {d18-d19}, [r5]
vneg.f32 q9,q9 <-- GCC intentionally causes stalls
add r7,r7,#16
vld1.32 {d22-d23}, [r8]
add r5,r1,r4
vneg.f32 q11,q11 <-- all of my interleaving is undone (why?!!?)
add r8,r3,#256 …Run Code Online (Sandbox Code Playgroud)