2017-11-18 137 views
0

我想用汇编语言编写一秒延迟循环,但我不确定循环的计数是什么,以便延迟1秒。如何在Assembly中为延迟循环设置正确的时序?

这是我到目前为止有:

MOV R1, #count 

DELAY_LOOP: 
      SUBS R1, R1, #1 

      BNE DELAY_LOOP 

我使用的是Beaglebone黑色。提前致谢!

+1

如果有可用的定时器中断,请尝试使用它。 – Thilo

+1

检查时钟速度以及您使用每条指令需要多少时钟。然后划分。或者,如果你懒惰并且不需要很高的精度,那么在该处粘贴一个大数字,然后用手表计时,然后将其缩小。 – Jester

+0

特别是在现代CPU中;对于不同的CPU,时钟速度可以不同,和/或可以在CPU运行时改变(由于电源管理 - 例如,由Beaglebone Black使用的SoC支持的“动态CPU频率缩放”功能);如果这些事情都不可能,那么“随机”进行循环的IRQ仍然需要比应有的更长的时间。由于这些原因,延迟循环几乎总是一个错误,因为确定正确的计数是不可能的(甚至当它不是一个可移植性和维护性灾难的错误时)。您应该使用实际的硬件计时器。 – Brendan

回答

0

很难为ARM获得这种权利,尤其是在操作系统上运行此操作时。不可能是准确的。纯粹的裸机,没有中断,你可以通过实验手动调整它,但是如果你改变了对齐方式,那么性能可能会发生很大的变化,这不仅是因为大多数人会假设的缓存,而且还会影响到获取线的位置和最佳点用于分支预测,如果存在分支预测以及它是如何实现的。我用这个确切的循环来证明这个问题有点微不足道。

这个问题不是ARM特有的任何事情流水线每次抓取事务往往要抓取多个指令,出于性能原因,抓取通常在对齐的边界上,并且预取缓冲区中存在一个接收这些数据的水印确定何时执行下一个读取操作,甚至这两个指令在一个循环中的对齐取决于它们在哪里可以对执行性能造成严重影响,基本上它执行两个读取行或每个循环一次,高速缓存在第一遍之后不相关,一个或两个读取行仍然可以访问缓存。

但是,这一切都因建筑而异。访问和缓冲到管道,arm,x86,powerpc等中的Mips都有所不同,并且可能因该体系结构的rev或generation而每隔三年变化一次,规则可能会针对该核心的下一个版本进行更改

ARM和MIPS以及其他基于IP的内核(其中芯片供应商实现内存系统)可以具有相同的核心版本,但是芯片供应商或家族对芯片供应商或家族差异可能/将会影响性能,所以即使您得到了相当关闭在一个芯片上,保持 相同的对准,并且基于芯片供应商/存储器侧的 ,其他核心设置性能可以不同。将dram加入这个公式中,其中内存的性能不是非确定性的,你只是让它变得更糟。

如果您回到预先流水线化的日子,一次执行一条指令,这是非常可预测的,常用的定时循环是使用较旧的PIC指令集完成的,极其可预测,并且并不少见请参阅使用定时循环而不是定时器。导致许多人尝试这样做后,他们在其他架构和体系结构上学习/在该架构上看到它(只是失败)。

这是一个非常教育性的练习,我建议你试试看。使用定时器作为参考,并在测试代码之前和之后使用单个加载指令对其进行理想的取样。如果你在操作系统上完成所有这些工作,可能会有足够的噪音,你实际上并没有看到差异的细节。您将创建其他循环窃取程序,并将其添加到总体计时中,特别是在测试代码之前和之后获取时间的呼叫。