Neon VLD 消耗的周期比预期的要多?

Posted

技术标签:

【中文标题】Neon VLD 消耗的周期比预期的要多?【英文标题】:Neon VLD consuming more cycles than what is expected? 【发布时间】:2013-02-14 07:21:49 【问题描述】:

我有一个简单的 asm 代码,它加载 NEON 的 12 个四位寄存器,并具有并行的成对添加指令以及加载指令(以利用双问题能力)。我已经验证了这里的代码:

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

正如我们所见,代码大约需要 13 个周期。但是当我在板上加载代码时,加载指令似乎每次加载需要超过一个周期,我验证并发现 VPADAL 需要 1 个周期,但 VLD1 需要超过一个周期。这是为什么呢?

我已经处理了以下内容:

    地址是 16 字节对齐的。 在指令vld1.64 d0, d1 [r0,:128]!中提供了对齐提示 在某些地方尝试了预加载指令 pld [r0, #192],但这似乎会增加周期,而不是实际减少延迟。

谁能告诉我我做错了什么,为什么会出现这种延迟?

其他细节:

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

【问题讨论】:

这是否反映了更多的现实? pulsar.webshaker.net/ccc/beta-sample-d3a7fe78(使用“beta”模拟器) @AkiSuihkonen,这怎么可能? VPADAL和VLD应该可以并行运行,从你给的模拟器链接看不像,还有为什么NEON要这么晚才启动? 抱歉,找不到简单的复制粘贴。但是,对您的问题/困惑的回答是,CPU 不能对外部存储器做出时序保证。让它成为一个缓存(如果它没有紧密集成)或更糟糕的外部存储器。这就是人们谈论 ddr2、ddr3 等的原因。它们具有不同的性能特征。你应该在这个阶段阅读你的整个系统,以了解你可以从 l1、l2 和 ram 获得多少停顿。 只是再添加一件事(如果有人以前不这样做,我稍后会尝试创建一个正确的答案),TRM 上的时间是“执行”/“发布”-所以我相信他们指的是把你的加载请求放在加载/存储队列中。 手册确实声称加载 qX @128 是一个单循环操作——但它必须预先假设一些东西——例如该地址已被预取。 【参考方案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)中随机出现垃圾。

【讨论】:

感谢您的回答,我已经在板上验证了我的代码,并且对于超过 64 字节的请求(cortex-a8 中的一个缓存行),即在我的代码中有四个加载请求之后,似乎发生了停滞,但我还不确定原因。所以在vld 加载请求之后的vpadal 似乎不是问题。我试过你的代码和男孩..!!摊位让我心脏病发作..!!使用相同寄存器累积结果的问题,导致严重停顿,阅读@auselen的答案here 很高兴知道使用相同的寄存器来累积结果。多个寄存器的交错将解决这个问题。另一件需要注意的事情是不要连续使用太多的 PLD,否则您也会停止内存读取,因为它将等待填充所有这些读取请求。内存速度很大程度上取决于您的硬件。最近我一直在使用带有 DDR3 内存的 Qualcomm MSM8074,内存吞吐量非常可观;该系统上的指令停顿和内存停顿大致相同。

以上是关于Neon VLD 消耗的周期比预期的要多?的主要内容,如果未能解决你的问题,请参考以下文章

常春藤下载的罐子比预期的要多

Conda remove 卸载的软件包比预期的要多

客户端通信层从 Advantage 数据库服务器接收到的数据比预期的要多

易达项目第一次冲刺周期第五天

为啥我的正则表达式模式收集的比我预期的要多?

UIView 动画动画的属性比我要求的要多