2012-01-23 42 views

回答

17

第二个“可能”会更好,因为将i与0比较比将i与10比较更容易,但我认为您可以使用其中的任何一个,因为编译器会优化它们。

+0

为什么比较'i'与0比10更容易? –

+1

+1削减新手一些松懈,因为他的答案是在正确的线 –

+10

因为大多数处理器有指令比较零?所以他们不需要加载'i'和10,减去他们,然后比较为零,但只是立即比较'i'为零。 – user1023979

1

编译器应该优化两个代码到同一个程序集,所以它没有什么区别。两者都采取同一时间。

更有效的讨论将是

for(int i=0;i<10;++i) //preincrement 
    { 
    } 

是否会快于

for(int i=0;i<10;i++) //postincrement 
    { 
    } 

因为,从理论上说,后加做额外的操作(返回参照旧值)。但是,即使这样,也应该对同一个组件进行优化。

没有优化,代码应该是这样的:

for (int i = 0; i < 10 ; i++) 
0041165E mov   dword ptr [i],0 
00411665 jmp   wmain+30h (411670h) 
00411667 mov   eax,dword ptr [i] 
0041166A add   eax,1 
0041166D mov   dword ptr [i],eax 
00411670 cmp   dword ptr [i],0Ah 
00411674 jge   wmain+68h (4116A8h) 

    for (int i = 0; i < 10 ; ++i) 
004116A8 mov   dword ptr [i],0 
004116AF jmp   wmain+7Ah (4116BAh) 
004116B1 mov   eax,dword ptr [i] 
004116B4 add   eax,1 
004116B7 mov   dword ptr [i],eax 
004116BA cmp   dword ptr [i],0Ah 
004116BE jge   wmain+0B2h (4116F2h) 

    for (int i = 9; i >= 0 ; i--) 
004116F2 mov   dword ptr [i],9 
004116F9 jmp   wmain+0C4h (411704h) 
004116FB mov   eax,dword ptr [i] 
004116FE sub   eax,1 
00411701 mov   dword ptr [i],eax 
00411704 cmp   dword ptr [i],0 
00411708 jl   wmain+0FCh (41173Ch) 

所以即使在这种情况下,速度是一样的。

+0

应该优化到相同的程序集......如果在循环内部使用“i”会怎么样? – Benoit

+0

@Benoit我的意思是相同数量的指令。 –

5

如果针对零的测试在硬件中进行优化,则递减到零的循环有时会更快。但这是一个微型优化,你应该知道它是否值得做。编译器通常会为你做优化,并且鉴于递减循环可能是一种更糟糕的意图表达方式,你通常坚持采用'正常'方法会更好。

7

我做不是认为两个循环的性能差别很大。

我想,当循环看起来像这样,它会变成不同的情况。

for(int i = 0; i < getMaximum(); i++) 
{ 
} 

for(int i = getMaximum() - 1; i >= 0; i--) 
{ 
} 

作为getMaximum()函数被调用一次或多次(假定它不是一个内联函数)

2

递增和递减(INC和DEC,当翻译成汇编命令)具有1相同的速度CPU周期。

但是,第二个可以对一些(例如SPARC)架构理论上更快因为没有10必须从内存(或缓存)获取:大多数架构与特compating时处理以优化的方式说明值0(通常有一个特殊的硬连线0寄存器用作操作数,所以没有寄存器必须被“浪费”以存储10用于每次迭代的比较)。

一个聪明的编译器(尤其是如果目标指令集RISC)将自身检测到并(如果你的计数器变量没有在循环使用),应用第二“减量DOWNTO 0”的形式。

请参阅答案https://stackoverflow.com/a/2823164/1018783https://stackoverflow.com/a/2823095/1018783进一步的细节。

+0

说到一条指令的执行时间在超标量体系结构上没有意义。桌面处理器在过去的15年中一直是超标量的(1993年的奔腾处理器是超标量的)。 – AProgrammer

+0

并非所有的现代硬件都是流水线的。嵌入式处理器与这种微型优化具有更多的相关性。此外,OP问题没有针对现代台式机处理器,所以我相信答案应该是通用的,并且地址也应该是20年前的处理器设计(通常仍然用作嵌入式CPU) –

+0

问题是,答案取决于它。这取决于处理器ISA是否有更好的支持。这取决于微架构是否能够利用ISA支持。如果编译器也能够利用(并且不能采取对抗措施,例如将10保存在寄存器中,则可以看到循环被执行了已知的少量时间并且完全展开或者使用辅助递减计数器) 。变数太多了。在上下文中衡量和衡量是唯一的答案,它对所有应用程序都有效。 – AProgrammer

0

同样,回答所有的微性能问题是措施,测量使用的背景下不要外推到其他情境。

计数指令执行时间不是很长一段时间没有一个极为成熟成为可能。

处理器和内存速度和引进缓存隐藏等待时间的部分之间的不匹配(但不是带宽)使得一组指令到存储器访问模式非常敏感的执行。这是你仍然可以通过相当高层次的思考进行优化。但是,这也意味着,如果不考虑内存访问模式,显然更糟的是,一旦完成,就会更好。

然后超标量(处理器可以同时做几件事情)和乱序执行(处理器可以在流中的前一个执行指令之前执行指令这一事实)使得基本计数无意义,即使忽略内存访问。您必须知道哪些指令需要执行(因此忽略部分结构不明智)以及处理器如果想要获得良好的先验估计,可以如何分组指令。

相关问题