image width = 4000
image height = 2000
number of iterations = width * height / 64 = 125 000
asm volatile(
"1: \n\t"
"prfm pldl1keep, [%[src], #128] \n\t"
"LD4 {v0.16B, v1.16B, v2.16B,v3.16B}, [%[src]], #64 \n\t" //5 cycles
"MOVI v10.16B, #12 \n\t" //1 cycle
"AND v4.16B, v0.16B, v10.16B \n\t" //1 cycle
"AND v5.16B, v1.16B, v10.16B \n\t" //1 cycle
"AND v6.16B, v2.16B, v10.16B \n\t" //1 cycle
"AND v7.16B, v3.16B, v10.16B \n\t" //1 cycle
"MOVI v11.16B, #20 \n\t" //1 cycle
"SUB v8.16B, v4.16B, v11.16B \n\t" //1 cycle
"SUB v9.16B, v5.16B, v11.16B \n\t" //1 cycle
"SUB v10.16B, v6.16B, v11.16B \n\t" //1 cycle
"SUB v11.16B, v7.16B, v11.16B \n\t" //1 cycle
"ST4 {v8.16B, v9.16B, v10.16B,v11.16B}, [%[dst]], #64 \n\t" //5 cycles
"subs %[simd_it], %[simd_it], #1 \n\t" //1 cycle
"bne 1b \n\t" //4 cycles
每次迭代大约 25 个时钟周期 每个图像 125 000 * 25 = 3 125 000 个周期
我在 ARM NEON 内联汇编中实现了示例代码(代码没有意义)。有(大约,我使用了来自 ARMv7 的信息,这是 ARMv8,但我不希望这个数字会更高)每个整个图像有 3,1M 个时钟周期。
我在频率为 1Ghz 的处理器上运行。如果处理器每秒执行 1G 个时钟周期,它应该在 4ms 内完成 3,1M 个周期。但我测量的时间约为 14 毫秒。
为什么不匹配?没有其他进程在同一核心上运行。
有条件分支,对于每次迭代(bne),它们将导致需要重新填充管道。如果条件跳过将被删除,而不是它,将编写数千行长的代码,它会快 3-4 倍吗?谢谢