我在汇编器中编写了一个霓虹灯优化的盒子过滤器。它在 i.MX6 (cortex-a9) 上运行。我现在谈谈机器的内存带宽问题,但这并不能解释我的观察:
我的代码(内联汇编器)
"loopSlide: \n\t"
"vld1.16 {q0-q1}, [%[add]]! \n\t"
"vld1.16 {q2-q3}, [%[add]]! \n\t"
"vsra.u16 q6, q0, #5 \n\t"
"vsra.u16 q7, q1, #5 \n\t"
"vsra.u16 q8, q2, #5 \n\t"
"vsra.u16 q9, q3, #5 \n\t"
"vld1.16 {q0-q1}, [%[sub]]! \n\t"
"vld1.16 {q2-q3}, [%[sub]]! \n\t"
"vshr.u16 q0, q0, #5 \n\t"
"vsub.u16 q6, q6, q0 \n\t"
"vshr.u16 q1, q1, #5 \n\t"
"vsub.u16 q7, q7, q1 \n\t"
"vst1.16 {q6-q7}, [%[sub]]! \n\t"
"vshr.u16 q2, q2, #5 \n\t"
"vsub.u16 q8, q8, q2 \n\t"
"vshr.u16 q3, q3, #5 \n\t"
"vsub.u16 q9, q9, q3 \n\t"
"vst1.16 {q8-q9}, [%[sub]]! \n\t"
"add %[dst], %[dst], %[inc] \n\t"
"pldw [%[dst]] \n\t"
"add %[add], %[add], %[inc] \n\t"
"add %[sub], %[sub], %[inc] \n\t"
"cmp %[src], %[end] \n\t"
"bne loopSlide \n\t"
整个图片需要 105 毫秒,这导致每条指令需要 25 个 CPU 周期!
仅去掉 vst 指令,算法速度高达 9.5 ms,符合我对内存带宽的预期。
现在我尝试交换输入和输出缓冲区,相同数量的加载和存储只用了不到 17 毫秒!如果我预料到会有差异,那么反过来,因为输入缓冲区之前已经被写入,所以它可能仍然在 L2 缓存中并且可以更快地读取,但是从未缓存的数据中读取并存储到的速度要快 6 倍缓存的...
两个缓冲区都具有 512 位对齐,并位于相同的内存区域,具有相同的缓存策略。
您是否知道问题的原因或尝试进一步检查的原因?