霓虹VLD消耗的周期比预期的多?

时间:2013-02-14 07:21:50

标签: embedded arm simd neon cortex-a8

我有一个简单的asm代码,它加载12个NEON的四个寄存器,并且具有并行的成对添加指令以及加载指令(以利用双重发布功能)。我在这里验证了代码:

http://pulsar.webshaker.net/ccc/sample-d3a7fe78

可以看出,代码大约需要13个周期。但是当我在板上加载代码时,加载指令似乎每个负载需要多个周期,我验证并发现VPADAL按照规定进行了1个周期,但VLD1需要多个周期。那是为什么?

我已经处理了以下事项:

  1. 地址对齐16字节。
  2. 已在说明vld1.64 {d0, d1} [r0,:128]!
  3. 中提供了对齐提示
  4. 尝试了预加载指令pld [r0, #192],但似乎会增加周期,而不是实际减少延迟。
  5. 有人能告诉我我做错了什么,为什么会出现这种延迟?

    其他细节:

    • 参考cortex-a8
    • arm-2009q1交叉编译工具链
    • 汇编编码

1 个答案:

答案 0 :(得分:1)

您的代码执行速度比预期慢得多,因为它目前正在编写,导致管道停滞的完美风暴。在任何具有流水线架构的现代CPU上,指令可以在理想条件下在一个周期内执行。理想的条件是指令不等待存储器并且没有任何寄存器依赖性。您编写代码的方式,您不允许延迟读取内存并使下一条指令取决于读取结果。这导致了最糟糕的性能。另外,我不确定为什么你要将成对的累加添加到多个寄存器中。尝试这样的事情:

    veor.u16 q12,q12,q12     @ clear accumulated sum
top_of_loop:
    vld1.u16 {q0,q1},[r0,:128]!
    vld1.u16 {q2,q3},[r0,:128]!
    vpadal.u16 q12,q0
    vpadal.u16 q12,q1
    vpadal.u16 q12,q2
    vpadal.u16 q12,q3
    vld1.u16 {q0,q1},[r0,:128]!
    vld1.u16 {q2,q3},[r0,:128]!
    vpadal.u16 q12,q0
    vpadal.u16 q12,q1
    vpadal.u16 q12,q2
    vpadal.u16 q12,q3
    subs r1,r1,#8
    bne top_of_loop

在执行添加之前尝试使用不同数量的加载指令。关键是您需要在使用目标寄存器之前留出时间进行读取。

注意:使用Q4-Q7是有风险的,因为它们是非易失性寄存器。在Android上,你会得到随机垃圾(特别是Q4)。