最快的轮询循环-如何减少1个CPU周期?

弗格里厄

在ARM Cortex M3(类似于STM32F101)上的实时应用中,我需要尽可能紧密地轮询内部外设的寄存器,直到其为零为止。我使用位带访问适当的位。(工作中的)C代码是

while (*(volatile uint32_t*)kMyBit != 0);

该代码被复制到片上可执行RAM中。经过一些手动优化²后,轮询循环降至以下时间,我将³计时为6个周期:

0x00600200 681A      LDR      r2,[r3,#0x00]
0x00600202 2A00      CMP      r2,#0x00
0x00600204 D1FC      BNE      0x00600200

如何降低投票不确定性?5个周期的循环将满足我的目标:在归零后,尽可能接近15.5个周期采样相同的位。

我的规范要求至少在6.5个CPU时钟周期内可靠地检测到低脉冲。如果持续时间少于12.5个周期,则将其可靠地分类为短;并持续对其进行超过18.5个周期的可靠分类。脉冲与CPU时钟没有定义的相位关系,这是我唯一的准确时序参考。这需要最多5个时钟的轮询循环。实际上,我正在仿真运行在具有数十年历史的8位CPU上的代码,该CPU可以按5个时钟周期进行轮询,而这已经成为规范。


我尝试通过在循环之前插入NOP来补偿代码对齐,这是我尝试过的许多变体,但从未观察到更改。

我试图反转CMP和LDR,但仍然得到6个周期:

0x00600200 681A      LDR      r2,[r3,#0x00]
; we loop here
0x00600202 2A00      CMP      r2,#0x00
0x00600204 681A      LDR      r2,[r3,#0x00]
0x00600206 D1FC      BNE      0x00600202

这是8个周期

0x00600200 681A      LDR      r2,[r3,#0x00]
0x00600202 681A      LDR      r2,[r3,#0x00]
0x00600204 2A00      CMP      r2,#0x00
0x00600206 D1FB      BNE      0x00600200

但这是9个周期:

0x00600200 681A      LDR      r2,[r3,#0x00]
0x00600202 2A00      CMP      r2,#0x00
0x00600204 681A      LDR      r2,[r3,#0x00]
0x00600206 D1FB      BNE      0x00600200

¹在没有中断发生的情况下,测量该位为低电平的时间。

²最初的编译器生成的代码使用r12作为目标寄存器,并向循环添加4个代码字节,花费1个周期。

³给定的数字是通过一个假定为周期精确的实时STIce仿真器及其仿真器触发功能获得的,该仿真器在寄存器的地址上读取。以前,我在循环中尝试了带有断点的“状态”计数器,但是结果取决于断点的位置。单步甚至更糟:它总是为LDR提供4个周期,而这至少有时会降至3个周期。

alex_mv

如果我对问题的理解正确,则不一定需要减少循环周期,而可以减少随后采样之间的周期数(即LDR指令)。但是每次迭代可以有多个LDR。您可以尝试如下操作:

    ldrb    r1, [r0]

loop:
    cbz     r1, out
    ldrb    r2, [r0]
    cbz     r2, out
    ldrb    r1, [r0]
    b       loop

out:

两个LDRB指令之间的间距会有所不同,因此样本的间距不会均匀。

这可能会稍微延迟退出循环,但是从问题描述中我无法说出它是否重要。

我碰巧可以访问精确到周期的M7模型,并且当过程使您的原始循环稳定时,M7在每个迭代中以3个周期运行(意味着每3个周期LDR),而上面建议的循环以4个周期运行,但是现在有那里有两个LDR(因此,每2个周期LDR)。采样率肯定提高了。

值得赞扬的是,@ Peter Cordes在评论中建议与CBZ一起休息

诚然,如果您追求的是采样率,M3的速度会更慢,但是仍然值得一试。

您也可以检查LDRB而不是LDR(如上面的代码)是否有任何更改,尽管我不希望如此。

UPD:我还有另一个2-LDR循环版本,该版本在M7上完成了3个周期,您可以尝试一下(也可以通过CBZ中断方便地平衡循环后的路径):

    ldr     r1, [r0]

loop:
    ldr     r2, [r0]
    cbz     r1, out_slow
    cbz     r2, out_fast
    ldr     r1, [r0]
    b       loop

out_fast:
    /* NOPs as required */

out_slow:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

RunLoop如何减少CPU周期

来自分类Dev

如何延迟循环周期?

来自分类Dev

JavaScript提供了许多类型的循环,例如for,for(reverse),for ... of,for ... in,foreach,forawait。哪一个最快?

来自分类Dev

.NET Framework中最快的循环条件是哪一个?

来自分类Dev

是CPU提取/执行周期是“事件循环”吗?

来自分类Dev

如何减少循环时间?

来自分类Dev

如何减少循环时间

来自分类Dev

While循环最快的方法

来自分类Dev

减少轮询Jenkins节点的时间

来自分类Dev

尽管迭代之间有依赖性,循环仍需不到1个周期

来自分类Dev

如何在sailsjs生命周期方法中循环一个集合?

来自分类Dev

轮询如何比中断更快

来自分类Dev

DPDK如何完成轮询?

来自分类Dev

如何匿名轮询?

来自分类Dev

轮询如何比中断更快

来自分类Dev

轮询C中的时钟周期数w

来自分类Dev

减少计数值以重复循环周期不起作用。python中的for循环具有一个异常处理程序,该异常处理程序具有一个continue语句

来自分类Dev

减少对象列表的最快方法

来自分类Dev

如何减少包含2个for循环的这段代码的运行时间?

来自分类Dev

在不使用数组或循环的情况下,找到五个给定数字中第三大数字的最快方法?

来自分类Dev

如何使用r中的for循环使用以前的观察来预测下一个周期?

来自分类Dev

如何通过减少迭代来构建循环

来自分类Dev

Checkers算法:如何减少嵌套的for循环

来自分类Dev

如何减少数组中的循环参数

来自分类Dev

如何使用代码sqlserver减少while循环

来自分类Dev

zmq轮询器如何工作?

来自分类Dev

如何实现PriorityBlockingQueue的轮询顺序?

来自分类Dev

如何轮询目录中的文件

来自分类Dev

如何使用Observables实施轮询?

Related 相关文章

  1. 1

    RunLoop如何减少CPU周期

  2. 2

    如何延迟循环周期?

  3. 3

    JavaScript提供了许多类型的循环,例如for,for(reverse),for ... of,for ... in,foreach,forawait。哪一个最快?

  4. 4

    .NET Framework中最快的循环条件是哪一个?

  5. 5

    是CPU提取/执行周期是“事件循环”吗?

  6. 6

    如何减少循环时间?

  7. 7

    如何减少循环时间

  8. 8

    While循环最快的方法

  9. 9

    减少轮询Jenkins节点的时间

  10. 10

    尽管迭代之间有依赖性,循环仍需不到1个周期

  11. 11

    如何在sailsjs生命周期方法中循环一个集合?

  12. 12

    轮询如何比中断更快

  13. 13

    DPDK如何完成轮询?

  14. 14

    如何匿名轮询?

  15. 15

    轮询如何比中断更快

  16. 16

    轮询C中的时钟周期数w

  17. 17

    减少计数值以重复循环周期不起作用。python中的for循环具有一个异常处理程序,该异常处理程序具有一个continue语句

  18. 18

    减少对象列表的最快方法

  19. 19

    如何减少包含2个for循环的这段代码的运行时间?

  20. 20

    在不使用数组或循环的情况下,找到五个给定数字中第三大数字的最快方法?

  21. 21

    如何使用r中的for循环使用以前的观察来预测下一个周期?

  22. 22

    如何通过减少迭代来构建循环

  23. 23

    Checkers算法:如何减少嵌套的for循环

  24. 24

    如何减少数组中的循环参数

  25. 25

    如何使用代码sqlserver减少while循环

  26. 26

    zmq轮询器如何工作?

  27. 27

    如何实现PriorityBlockingQueue的轮询顺序?

  28. 28

    如何轮询目录中的文件

  29. 29

    如何使用Observables实施轮询?

热门标签

归档