我正在霓虹灯和手臂组件中实现计算机视觉卷积算法,其中每个像素被九个自身像素和相邻像素的和积替代.主循环看起来像这样:
.loop:
vld1.u8 {d0}, [line_prev]
add line_prev, line_prev, #1
vld1.u8 {d1}, [line_prev]
add line_prev, line_prev, #1
vld1.u8 {d2}, [line_prev]
add line_prev, line_prev, #6
vld1.u8 {d3}, [line]
add line, line, #1
vld1.u8 {d4}, [line]
add line, line, #1
vld1.u8 {d5}, [line]
add line, line, #6
vld1.u8 {d6}, [line_next]
add line_next, line_next, #1
vld1.u8 {d7}, [line_next]
add line_next, line_next, #1
vld1.u8 {d8}, [line_next]
add line_next, line_next, #6
//Everything is loaded now. Let's multiply and sum
vmull.u8 q10, d0, d10 //d10 to d18 holds the kernel matrix values
vmlal.u8 q10, d1, d11
vmlal.u8 q10, d2, d12
vmlal.u8 q10, d3, d13
vmlal.u8 q10, d4, d14
vmlal.u8 q10, d5, d15
vmlal.u8 q10, d6, d16
vmlal.u8 q10, d7, d17
vmlal.u8 q10, d8, d18
vshrn.u16 d4, q10, d19 //Shift the sum by the value in d19
vst1.u8 {d4}, [out]! //Store result
subs temp, temp, #8 //We have processed 8 pixels
bgt .loop
Run Code Online (Sandbox Code Playgroud)
如何优化(在速度方面)此循环?是否有更聪明的事情来加载像素.此外,q11 ...是可用的:我应该使用它们并行vmull和mlal指令吗?
尝试交错加载代码和数学代码.你想要一些加载/使用延迟(目标是几个周期),但交错负载和数学通常更好.
加载Q寄存器一次取16个值可能有帮助,而不是D寄存器,如果你可以工作寄存器空间以适应它全部.按照上面的流加载/使用有帮助(你经常可以使用一个物理寄存器两个单次迭代中的值).
使用预加载.