为了账号安全,请及时绑定邮箱和手机立即绑定

倒数比倒数快吗?

倒数比倒数快吗?

UYOU 2019-11-25 10:45:29
我们的计算机科学老师曾经说过,由于某种原因,倒数比倒数更有效。例如,如果您需要使用FOR循环,而循环索引未在某处使用(例如在屏幕上打印N *行),则表示这样的代码:for (i = N; i >= 0; i--)    putchar('*');  优于:for (i = 0; i < N; i++)    putchar('*');  是真的吗 如果是这样,有人知道为什么吗?
查看完整描述

3 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

是真的吗 如果是这样,有人知道为什么吗?

在远古时代,当仍然用手从熔融硅石中切出计算机,8位微控制器在地球上漫游以及您的老师年轻(或您的老师的老师年轻)时,就有一条通用的机器指令称为减量和跳过如果为零(DSZ)。热门汇编程序员使用此指令来实现循环。后来的机器得到了更奇妙的指令,但是仍然有很多处理器在上面比较零的东西比与其他东西比较便宜。(即使在某些现代RISC机器(例如PPC或SPARC)上也是如此,它们保留整个寄存器始终为零。)

因此,如果将循环绑定为零而不是N,那会发生什么?

  • 您可以保存注册

  • 您可能会使用较小的二进制编码获得比较指令

  • 如果前面的指令碰巧设置了一个标志(可能仅在x86系列机器上),则您甚至可能不需要显式的比较指令。

这些差异是否可能导致对现代乱序处理器上的真实程序进行任何可衡量的改进?不大可能。实际上,即使您在微基准测试上也能表现出可衡量的改进,我会印象深刻。

摘要:我拍了一下你的老师脑袋! 您不应该学习有关如何组织循环的过时的伪事实。您应该了解,关于循环的最重要的事情是确保循环终止,产生正确的答案并且易于阅读 我希望您的老师将重点放在重要的东西上,而不是神话。


查看完整回答
反对 回复 2019-11-25
?
烙印99

TA贡献1829条经验 获得超13个赞

以下是某些硬件上可能发生的情况,具体取决于编译器可以推断出所用数字的范围:使用递增循环,您i<N每次循环时都必须进行测试。对于减量版本,进位标志(设置为减法的副作用)可能会自动告诉您是否i>=0。这样可以节省循环时间的测试时间。

实际上,在现代流水线处理器硬件上,由于没有从指令到时钟周期的简单1-1映射,因此这些东西几乎可以说是无关紧要的。(尽管我可以想象,如果您正在执行诸如从微控制器生成精确定时的视频信号之类的事情的话,但是无论如何您还是会用汇编语言编写。)


查看完整回答
反对 回复 2019-11-25
?
侃侃无极

TA贡献2051条经验 获得超10个赞

在Intel x86指令集中,构建循环以递减计数到零的过程通常比以循环计数到非零退出条件的循环要少。具体来说,ECX寄存器传统上用作x86 asm中的循环计数器,并且Intel指令集具有特殊的jcxz跳转指令,该指令会测试ECX寄存器是否为零并根据测试结果进行跳转。

但是,除非您的循环对时钟周期计数非常敏感,否则性能差异可以忽略不计。与递增计数相比,递减计数到零可能会使循环的每个迭代减少4或5个时钟周期,因此,它实际上是新颖的事物,而不是有用的技术。

另外,如今,一个好的优化编译器应该能够将向上计数的循环源代码转换为向下计数的零机器代码(取决于您使用循环索引变量的方式),因此实际上没有任何理由要在其中编写循环只是在这里和那里挤压一个或两个周期的奇怪方法。


查看完整回答
反对 回复 2019-11-25
  • 3 回答
  • 0 关注
  • 686 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信