C++ 比较int的正向和反向循环,其中一个极限为0
考虑C++ 比较int的正向和反向循环,其中一个极限为0,c++,loops,C++,Loops,考虑for循环的示例: for(int i = 0; i <= NUM; i++); // forward for(int i = NUM; i >= 0; i--); // reverse for(int i=0;i=0;i--);//颠倒 我用gcc(linux-64)测试了这个循环。在没有任何优化标志的情况下,正向循环速度更快,而在优化到O3/O4时,反向循环速度更快 我在某处听说,由于更好的缓存替换技术,前向循环速度更快 我个人认为,反向循环应该更快(无论NUM是常量
for
循环的示例:
for(int i = 0; i <= NUM; i++); // forward
for(int i = NUM; i >= 0; i--); // reverse
for(int i=0;i=0;i--);//颠倒
我用gcc(linux-64)测试了这个循环。在没有任何优化标志的情况下,正向循环速度更快,而在优化到O3/O4时,反向循环速度更快
我在某处听说,由于更好的缓存替换技术,前向循环速度更快
我个人认为,反向循环应该更快(无论NUM是常量还是变量)。因为任何微处理器都有一条与0比较的指令,i>=0
(即JLZ(小于零时跳转)
和等效指令)
这个问题有确定的答案吗?也许增加一个循环变量更为常见,以至于CPU的分支预测在这些变量上工作得更好 通过编译器优化,您的循环可能会被展开,因为我正确地假设,您的
NUM
是一个#define
常量,因此速度更快。不,这绝对没有确定的答案。您将看到两个不同的抽象级别
就性能而言,C++完全没有什么可说的。它指定了一个执行C++代码的虚拟机,它覆盖了功能,但它不包括底层环境的性能(a)。
其中哪一个更快将取决于多种因素。您可能会发现自己运行在一个CPU上,它不区分与任意值的比较和与零的比较
您可能会发现一种架构,其中寄存器的递增速度是寄存器递减速度的十倍,尽管这看起来很奇怪
您甚至可能会发现一个完全没有减量、加法或减法指令的脑死亡架构,并且您必须通过调用increment 2n-1次来模拟减量(其中n
是字大小)
一句话:除非你想看一个非常特定的CPU、编译器等,否则你不能假设你知道引擎盖下发生了什么
您应该首先优化代码的可读性。如果您需要以不断增加的方式处理问题,请使用第一个选项。如果是递减方式,则使用后者。如果这两种方法看起来同样自然,那么选择最快的一种,通过基准测试或对底层架构和汇编代码的分析发现。但只有当您有特定的性能问题时才这样做,否则您是在浪费精力
在任何情况下,由于您几乎肯定会使用i
进行某些操作,因此,无论您以最快的方式获得的性能有多小的提高,都可能会被您现在必须在循环中计算NUM-i
的事实所淹没(当然,除非编译器比开发人员更聪明,根据我在gcc
中看到的,这是完全可能的)
(a) 它确实指定了某些与性能相关的内容,例如容器库中某些内容的时间复杂度,但没有具体说明您要询问的内容,即正向循环还是反向循环更快。虽然它并没有真正回答您的问题,但它只是一个想法。这个循环如何:
int i = NUM + 1;
while ( i --> 0 )//it looks as if i goes to zero (like in calculus)!
{
}
缓存替换技术只有在发生冲突时才会生效。可能
NUM
不够大,不足以产生效果,或者虚拟内存到物理内存的映射恰好有利于缓存替换算法
试图潜在地保存一条机器指令表明对编译器缺乏信任。如果这么简单,优化器肯定会知道这一点!linux-64=x86_64或ia64或alpha64或sparc64?一个词:微优化。这一差异肯定不会引起任何人的注意。出于兴趣,会进行预增量或预deCeDeCe改变你的观察?@科迪-如果目的是了解更多的硬件而不是过早优化,那么问题可能是非常有趣的吗?你看发射的汇编代码吗?如果代码< num=InthMax < /C> >未定义的行为;-pIf你<代码>定义< <代码> > C++中的常数整型,我将拥有你的SCAL。p、 真的!我不知道,我只是从大写字母猜。但无论如何,这不是重点。我的意思是,如果编译器知道,变量永远不会改变,它可能会展开循环。同意
缺乏信任的部分。但我很想知道底层的事情。