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、 真的!我不知道,我只是从大写字母猜。但无论如何,这不是重点。我的意思是,如果编译器知道,变量永远不会改变,它可能会展开循环。同意
缺乏信任的部分。但我很想知道底层的事情。