如何在Assembly中设置延迟循环的正确时间?

时间:2017-11-18 01:11:28

标签: assembly arm

我想用汇编语言编写一秒延迟循环,我不确定循环的计数是多少,因此它会延迟1秒。

这是我到目前为止所做的:

MOV   R1, #count

DELAY_LOOP:  
             SUBS   R1, R1, #1

             BNE  DELAY_LOOP

我正在使用Beaglebone Black。提前谢谢!

1 个答案:

答案 0 :(得分:0)

很难为ARM做到这一点,特别是如果您在操作系统上运行它。不可能准确。纯粹的裸金属,没有中断,你可以通过实验手动调整它,但是如果你改变对齐方式,性能可能会有相当大的变化,这不仅仅是因为大多数人会假设的缓存,而且也取决于获取线所在的位置和甜点用于分支预测,如果存在分支预测以及如何实现分支预测。我使用这个确切的循环来证明这个问题它有点微不足道。

问题不是特定于ARM的任何流水线通常会为每个提取事务获取多个指令,出于性能原因,提取通常在对齐的边界上,并且预取缓冲区中有一个水印接收此数据确定何时进行下一次获取,即使这两个指令在一个循环中的对齐取决于它们所处的位置会对执行性能造成严重破坏,基本上它是执行两个获取行或每个循环一个,缓存在第一遍之外是不相关的,一条或两条获取行仍然可以访问缓存。

但这一切都因建筑而异。获取和缓冲到管道,手臂,x86,powerpc等的Mips都有所不同,并且可能会因为该架构的转换或生成每三年变化一次,规则可能会针对该核心的下一个版本而改变

ARM和MIPS以及其他基于IP的内核(芯片供应商实现内存系统)您可以拥有相同的核心版本,但 芯片供应商或家庭与芯片供应商或家庭的差异可以/将会 影响性能,所以即使你在一块芯片上有点接近,也要保持好 相同的对齐和其他核心设置性能可以基于不同 在芯片供应商/内存方面。添加dram到这个等式,其中 记忆的表现不是不确定的,你只是让它变得更糟。

如果你回到预先流水线的日子,执行是一次一条指令,非常可预测,一个常用的定时循环是用旧的PIC指令集完成的,非常可预测,并且不常见使用定时循环而不是计时器。在他们用其他mcus和架构学习/看到它的架构之后,导致很多人试图这样做(仅失败)。

这是一项非常有教育意义的练习,我建议你尝试一下。使用定时器作为参考,并在测试代码之前和之后使用单个加载指令对其进行理想的采样。如果您在操作系统上执行所有这些操作,可能会有足够的噪音,您实际上并未在差异中看到详细信息。您将创建其他循环窃取程序,这些循环程序被添加到整体计时,特别是调用以获取测试代码之前和之后的时间。