Hi All,
This is probably a very basic question but here goes anyways -- which would be faster in C/C++ (or would it make no difference at all?):
while(condition) { ... }
OR
while(true) { ... if(condition) break; ... }
Thanks, Siddhesh
--- Siddhesh Poyarekar wrote:
Hi All,
This is probably a very basic question but here goes anyways
Is it?
-- which would be faster in C/C++ (or would it make no difference at all?):
while(condition) { ... }
OR
while(true) { ... if(condition) break; ... }
I'm not sure, if my answer is correct, but I would think of it in the following way. The compiler would produce an appropriate code for each of /block-code/ mentioned above, and the one with less number of instruction set, would (should?) perform faster.
If this is part of a bigger program, using boolean variables with while loop, could prove useful.
-- FSF of India Associate Fellow - http://www.gnu.org.in http://www.somaiya.edu/sksasc ubunturos @ freenode
Why delete messages? Unlimited storage is just a click away. Go to http://help.yahoo.com/l/in/yahoo/mail/yahoomail/tools/tools-08.html
On 7/30/07, Roshan d_rosh2001@yahoo.co.in wrote:
If this is part of a bigger program, using boolean variables with while loop, could prove useful.
It is, and the way it has actually been used makes it look even more suspicious:
while(true) { if(condition1) { do_something; break; } if(condition2) { do_something; break; }
do_something;
break; }
Besides being unreadable, does this code have any performance drawbacks as well? My guess is that it would always ruin instruction pipelining since the loop code will be pre-fetched/cached. But that's just a hunch.
I think I'll have to search for my Computer Architecture book now ;)
On Mon, 2007-07-30 at 14:24 +0530, Siddhesh Poyarekar wrote:
It is, and the way it has actually been used makes it look even more suspicious:
while(true) { if(condition1) { do_something; break; } if(condition2) { do_something; break; }
do_something;
break; }
Besides being unreadable, does this code have any performance drawbacks as well? My guess is that it would always ruin instruction pipelining since the loop code will be pre-fetched/cached. But that's just a hunch.
Umm...the question you asked is very implementation specific. It not only depends on how the compiler optimizes the code but also on the executable code it produces and how exactly the processor executes it.
So unless you want to restrict your code to particular compiler and a particular processor you shouldn't be really worrying about these issues.
I think I'll have to search for my Computer Architecture book now ;)
No point unless you are targeting a particular processor and a compiler.
On 7/30/07, Dinesh Joshi dinesh.a.joshi@gmail.com wrote:
Umm...the question you asked is very implementation specific. It not only depends on how the compiler optimizes the code but also on the executable code it produces and how exactly the processor executes it.
I'm not considering compiler optimization at all -- let us go with the assumption that we have disabled compiler optimization.
The above example could be implemented as a series of if() else if()... but it isn't and I'm trying to find a reason why. Is there a case where the while(true) approach actually performs better or equal?
On 7/30/07, Siddhesh Poyarekar wrote:
On 7/30/07, Dinesh Joshi wrote: I'm not considering compiler optimization at all -- let us go with the assumption that we have disabled compiler optimization.
Its not even a question about compiler optimizations. Its just how the compiler will treat the code block and generate object code for it. The C language doesn't define how that compiler should treat the block hence you have no control over which piece of code will work better.
The above example could be implemented as a series of if() else if()... but it isn't and I'm trying to find a reason why. Is there a case where the while(true) approach actually performs better or equal?
All I can see is that the first example can have only 1 condition while the other blcok can break over several conditions. Care to explain in more detail so that your dilemma is more clear in everyone's mind?
On 7/30/07, Dinesh Joshi dinesh.a.joshi@gmail.com wrote:
All I can see is that the first example can have only 1 condition while the other blcok can break over several conditions. Care to explain in more detail so that your dilemma is more clear in everyone's mind?
Ok I guess the confusion is because I posted two queries without explicitly detailing them. The code posted below is in C/C++. Here they are:
1) Which is more efficient, or is there no difference between them:
while(true) { ... if(condition) break; }
OR
while(condition) { ... }
2) Does this code only look bad or does it execute slowly as well:
while(true) { if(condition1) { do_something; break; } if(condition2) { do_something; break; }
do_something;
break; }
Apologies for causing the confusion.
On 7/30/07, Siddhesh Poyarekar siddhesh.poyarekar@gmail.com wrote:
- Which is more efficient, or is there no difference between them:
while(true) { ... if(condition) break; }
OR
while(condition) { ... }
Hmm...well, it depends. The first block will break after executing some instructions. It actually looks like a Do...While loop since it executes instructions FIRST and then CHECKs the condition.
The second block first checks the condition and then executes the instructions. So it really depends on the specific code. The general blocks can't be compared really as they are NOT the same.
- Does this code only look bad or does it execute slowly as well:
while(true) { if(condition1) { do_something; break; } if(condition2) { do_something; break; }
do_something;
break; }
Actually that piece of code will execute only ONCE. Why? Because you have a break just before the closing brace of the while loop.
If we ignore that then, again depends on the specific purpose of the code. Yes it does look bad and yes it will work slowly if the three conditions are rarely executed. It then makes sense to take them out and execute them separately but then thats not always possible.
On 7/30/07, Dinesh Joshi dinesh.a.joshi@gmail.com wrote:
Hmm...well, it depends. The first block will break after executing some instructions. It actually looks like a Do...While loop since it executes instructions FIRST and then CHECKs the condition.
The second block first checks the condition and then executes the instructions. So it really depends on the specific code. The general blocks can't be compared really as they are NOT the same.
OK, but is it worth spending some time evaluating my construct to actually avoid the while(true)?
Actually that piece of code will execute only ONCE. Why? Because you have a break just before the closing brace of the while loop.
Yes it will execute only once; that was not a typo ;) I guess it is meant as a replacement for the try-catch block. I'm guessing the reason is that no optimization is done inside try-catch blocks since any call inside the try block may lead to a branch.
The above example could be implemented as a series of if() else if()... but it isn't and I'm trying to find a reason why. Is there a case where the while(true) approach actually performs better or equal?
While writing C code for ARM, I would prefer if() else if() or switch command. The while(true) + if() would add extra condition checking and would be slower.
just ... from a newbie.
Warm Regards,
Mukund Deshmukh, Beta Computronics Pvt Ltd. 10/1 IT Park, Parsodi, Nagpur -440022 India. Web site - http://betacomp.com
On 8/1/07, Mukund Deshmukh wrote:
While writing C code for ARM, I would prefer if() else if() or switch command. The while(true) + if() would add extra condition checking and would be slower.
How will it add an extra condition? The compiler is smart enough to understand while( true ) is an unconditional loop and will not generate the code for a condition check instead it'll just put a JMP instruction back to the start of the block. So no overheads there.
On 7/30/07, Dinesh Joshi dinesh.a.joshi@gmail.com wrote:
How will it add an extra condition? The compiler is smart enough to understand while( true ) is an unconditional loop and will not generate the code for a condition check instead it'll just put a JMP instruction back to the start of the block. So no overheads there.
Exactly. So does this happen even with optimization turned off? If it does then shouldn't my code in query two cause a miss in the instruction pipeline all the time?
On 7/30/07, Siddhesh Poyarekar wrote:
On 7/30/07, Dinesh Joshi wrote:
How will it add an extra condition? The compiler is smart enough to understand while( true ) is an unconditional loop and will not generate the code for a condition check instead it'll just put a JMP instruction back to the start of the block. So no overheads there.
Exactly. So does this happen even with optimization turned off? If it does then shouldn't my code in query two cause a miss in the instruction pipeline all the time?
Again, we come to the implementation part. Depends on the processor on which you run the code on. It all depends on the branch prediction logic. But here branch prediction doesn't come into picture! The JMP instruction is an unconditional jump. Your code will generate assembly like this:
.file "test2.c" .text .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $16, %esp .L2: addl $1, -8(%ebp) jmp .L2 .size main, .-main .ident "GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3)" .section .note.GNU-stack,"",@progbits
See the unconditional JMP instruction that GCC generated?
The C source for this assembly is :
int main() { int i; while( 1 ) { i++; } return 0; }
Now get it ?
On 7/30/07, Dinesh Joshi dinesh.a.joshi@gmail.com wrote:
Exactly. So does this happen even with optimization turned off? If it does then shouldn't my code in query two cause a miss in the instruction pipeline all the time?
Again, we come to the implementation part. Depends on the processor on which you run the code on. It all depends on the branch prediction logic. But here branch prediction doesn't come into picture! The JMP instruction is an unconditional jump. Your code will generate assembly like this:
Firstly, good example.
True, the implementation is processor-specific. But AFAIK almost all processors in the market today implement instruction pipelining. Differences lie in the number of instructions pre-fetched and the branch prediction technique (anything else that impacts this example?). Branch prediction does not figure here since the while(true) becomes an unconditional jump. The actual number of instructions pre-fetched only tell us about the degree to which the impact occurs in case of a miss; I'm not concerned about the degree, I'm only concerned about whether it does make an impact.
The code inside the while block remains keeps cycling in the pipeline until the conditional branch somewhere in between evaluates to true, which causes a jump to the statement outside the loop. The entire loop code will have to be unloaded since all of it is a miss. Bigger the loop, larger the miss (to the extent of the max number of instructions pre-fetched).
On Mon, 2007-07-30 at 23:37 +0530, Siddhesh Poyarekar wrote:
Firstly, good example.
True, the implementation is processor-specific. But AFAIK almost all processors in the market today implement instruction pipelining. Differences lie in the number of instructions pre-fetched and the branch prediction technique (anything else that impacts this example?). Branch prediction does not figure here since the while(true) becomes an unconditional jump. The actual number of instructions pre-fetched only tell us about the degree to which the impact occurs in case of a miss; I'm not concerned about the degree, I'm only concerned about whether it does make an impact.
Well its a tough question. Well, IIRC my SP classes then there will be an impact. But most modern processors minimize it by having multiple multi-stage pipelines. The processor rarely runs out of code to execute. When a miss occurs it is definitely going to dump that pipeline and while it is being prepared it will switch to the other pipeline. Here I'm talking specifically of the pentium architecture.
The code inside the while block remains keeps cycling in the pipeline until the conditional branch somewhere in between evaluates to true, which causes a jump to the statement outside the loop. The entire loop code will have to be unloaded since all of it is a miss. Bigger the loop, larger the miss (to the extent of the max number of instructions pre-fetched).
Yes, you are right here.