I was wondering what was faster. Is it when you do a for loop with only one instruction (i.e 1=1) 9 times or is it when you go through 9 if condition?
I think the ifs are faster because you don't need to check for instruction in the loop
It should be pretty much the same - because for loops are essentially checking if a condition is true and running a block of code - very similar to if statements.
For details on how for loops and if statement are typically implemented in assembly - have a look at https://en.wikibooks.org/wiki/X86_Disassembly/Loops and complex IF statement in assembly
Related
This question already has answers here:
Difference between "while" loop and "do while" loop
(16 answers)
Closed 7 years ago.
can anybody tell me the basic difference (in terms of efficiency) between the while loop and do while loop in c++ ?
I tried to search it through web but couldn't find the exact answer.
There is no difference in terms of efficiency. Both amount to a condition evaluation and a conditional jump.
If the optimizer does not insert redundant code, a top checked loop is slower because of the extra jump required. If the optimizer does insert redundant code, the top checked loop will be trivially slower because of the redundant code itself and because of its cache impact.
If the correct behavior is that the body is executed at least once, then a top checked loop is less efficient (by more than the cost of one extra execution of the condition). But that still is usually not a reason to choose bottom checking on the basis of efficiency. Choose the one that makes the code more understandable to a human maintainer.
Programmers are used to looking at while loops (top checked loops) in which the condition is trivially true (from a human point of view) on the first pass. The loop is still more readable top checked. If the first pass is so trivially true that even the compiler sees it (occurs less often than you might guess) then there is really no efficiency difference.
Often the condition you want to test cannot even be computed until once through the loop. Then I find a bottom checked loop more readable. The common practice of making dummy inputs to the condition in order to top check something trivially true, is just distracting.
The do while loop ensures that the body of the loop executes at least once.
it depends on how much you need to use it, i saw this good example of when you need to use the do while loop
Perhaps you've written a graphical program that runs an animation. When the game ends, you need to show your players the scoreboard. Of course, you need to run the animation loop at least once just to render the scoreboard. So: run your animation in the loop and do the conditional at the end to see if you should stop animating because the game is over.
I read a terrifying post recently where someone claimed that a switch statement in GLSL uses no conditional branching, and in fact causes every possible outcome to be run every time the switch is entered. This is worrying for me because I'm currently working on a deferred rendering engine which uses a few nested switch statements.
Does anyone know if there's any truth to this, and can it be backed up with any evidence?
Thanks!
I read a terrifying post recently where someone claimed that a switch statement in GLSL uses no conditional branching, and in fact causes every possible outcome to be run every time the switch is entered.
Neither of these is necessarily true. At least, not on today's hardware.
What happens is very dependent on the compiler and the underlying hardware architecture. So there is no one answer. But it is also very dependent on one other thing: what the condition actually is.
See, the reason why a compiler would execute both sides of a condition has to do with how GPUs work. GPUs gain their performance by grouping threads together and executing them in lock-step, with each thread group executing the exact same sequence of steps. With a conditional branch, this is impossible. So to do a true branch, you have to break up a group depending on which individual threads execute which branch.
So instead, if the two branches are fairly short, it'll execute them both and discard the particular values from the not-taken branch. The particular discarding of values doesn't require breaking thread groups, due to specialized opcodes and such.
Well, if the condition is based on an expression which is dynamically uniform (ie: an expression which is always the same within a draw call/context), then there is a good chance the compiler will not execute both sides. That it will do a true condition.
The reason being that, because the condition is dynamically uniform, all threads in the group will execute the same code. So there is no need to break a group of threads up to do a proper condition.
So if you have a switch statement that is based on a uniform variable, or expressions only involving uniform and compile-time constant variables, then there is no reason to expect it to execute multiple branches simultaneously.
It should also be noted that even if the expression is not dynamically uniform, the compiler will not always execute both branches. If the branches are too long or too different or whatever, it can choose to break up thread groups. This can lower performance, but potentially not as much as executing both groups. It's really up to the compiler to work out how to do it.
Is there any difference in performance in one big loop vs many small loops?
I need to iterate over 3 arrays with 64 elements each, and I also have to check for each item if it is NULL, if it is, I skip that iteration. Would it be better to write one big loop and insert 3 ifs inside of it, or write 3 small loops, one for each array?
A big loop could be faster because it has fewer branches in total (4 vs 6) and is slightly less code overall.
3 small branches will probably be faster on most modern CPU's because the cost of the branches for the loops is small, and splitting the loops up can make instruction fetching more efficient.
This is highly dependent on how much code you have in the loops, and also potentially on the positions of your branches within those loops. Branch prediction could be affected too, but this could go either way.
There is a higher possibility for a smaller loop to fit in a CPU cache, thus
execution could be far quicker than a larger loop which doesn't.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
When I was a freshman, our instructor allowed us to use break or continue in loops. I did it most of the time back then since it terminates/continues the loop. And now I'm in sophomore years, my instructor told me that the use of break/continue is not advisable. Can you tell me why? What affects break/continue by the way?
Some people think that it's bad to have a too complex control flow, which means things like break, continue and multiple returns. The reason is not technical, but mostly that complex control flow can make it harder to verify, test and and reason about a program.
It is however largely a matter of style, personal taste, and your overall structure. With small, well-purposed functions, there might be little to no harm in having multiple possible flows. In C++ in particular, early exit is a popular idiom and can often make code easier to follow.
At least in C, you should not be using break and/or continue "most of the time" (as your question says you used to do) to control the flow of your loops. Your loop condition should indicate under what circumstances the loop should stop; somebody maintaining your code should not have to dig through the code in the body of your loop to see what triggers the break that causes the loop to stop.
For example, let's say you want to read a number of integers from a file inputFile to see if one of the integers is 500. One way of structuring the loop is:
while (fgets (buffer, sizeof (buffer), inputFile)){
sscanf (buffer, "%d", &num);
if (num == 500)
break;
}
Here, the person reading your code has to read your entire while loop to figure out what you are actually looking for in the file. If you write this without the break:
while ((num != 500) && fgets (buffer, sizeof (buffer), inputFile))
sscanf (buffer, "%d", &num);
the loop condition itself tells the reader exactly what your code is trying to do, which makes it a lot more easy to understand quickly. Also, as a bonus, you have saved a few lines of code.
Now imagine a more complicated while or for loop, where the break is buried deep inside the body of the loop. It's easy to see why trying to find the break trigger would get annoying. Having a properly structured loop condition is much more, um, self-documenting.
There are, of course, cases where break and continue are in fact good ways to write the code. For example, if the condition at which the loop should end might occur in the middle of the loop execution, and there's a long set of statements that follow inside the loop, and executing those statements would add processing time without accomplishing anything useful, sure, go ahead and use the break. But those cases are the exception, not the "most of the time".
Most of the logic I've seen for reasoning about code correctness
supposes single entry/single exit. If your loops are filled
with break and continue, it becomes impossible to know
whether your loop invariants are met, or whether you always make
progress (so the loop won't be endless). (Note that the do
{ ... } while (...); loop also suffers from this; the loop
invariants aren't established the first time through, which can
lead to some surprises.)
Most of the cases where you are tempted to use break or
continue, you've probably made the loop (and the function
which contains it) too large and too complex.
Some would argue that something like:
for (;;) {
// ...
if ( conditionMet ) {
break;
}
// ...
}
would be acceptable for the classical loop and a half idiom; it
is single entry/single exit, after all, even if the exit isn't
quite where we expect it (and is very hard to find when reading
the code). The problem concerning loop invariants remains; the
aren't met before the if, at least the first time through.
Generally, a better solution would be to put the code before the
test into a separate function, which returns conditionMet, and
use:
while ( doLoopPrefix() ) {
doLoopSuffix();
}
(In general, if your loop is more than three or four lines, you
should refactor. Except maybe if it contains a single switch
statement, with a lot of cases.)
Is it better to calculate x-1 into a variable and then use that?
I have a for loop and inside (x-1). Is it better to create
new variable y=x-1, and then use y inside the loop, rather
then recalculate it many times in the for loop? I will save
many subtractions. Not sure if this is some optimization?
Don't under or over estimate the capabilities of the compiler.
Profile first.
Look at the assembly language listing of the optimized version for the function.
The compiler may be able to combine the X-1 with another instruction.
Wait until the code works completely and is robust before making optimizations. Often times, code is harder to debug when it is optimized and you could be wasting your time optimizing code that isn't used frequently.
If x does not change inside the loop, then the compiler will most likely optimize it and calculate it only once, so it should not matter. (Of course, if x does change inside the loop, then it goes without saying that you should recompute it inside the loop).
Aside from the optimization aspect, it is probably more important to write the code so it makes the most sense to another programmer (e.g., someone maintaining the code). If using x-1 inside the loop makes the code clearer, it is almost certainly better to write it that way. Unless the loop is extremely critical to overall performance, it is (in my opinion) better to focus on making the code easier to read.
Yes, that will help speed up your code. Anything that decreases the number of calculations you need to perform will increase the speed of your code, especially if your loop goes through a lot of iterations.
No need to do something over and over again if you can do it just once :)
This is assuming that x doesn't change during your loop, though. If x does change, then you'll need to recalculate it because y will be different each time through the loop.