Reputation:
There is something I don't understand with my code. I'm working with avr-gcc and optimizing my code for speed. I've read about loops, counting down and post/pre (de)crements, comparison with 0 and discovered something odd.
This code runs in 47s:
UInt8 ret, i;
i = UJ_THREAD_QUANTUM;
do {
ret = ujThreadPrvInstr(h, t);
if (ret == UJ_ERR_RETRY_LATER) {
// do not bother with the rest of time quantum if we're already stuck
ret = UJ_ERR_NONE;
break;
}
died = (t->pc == UJ_PC_DONE);
if (died) {
break;
}
if (ret != UJ_ERR_NONE) {
break;
}
} while(--i);
This code in 43s:
for (i = UJ_THREAD_QUANTUM; i >= 0; --i) {
ret = ujThreadPrvInstr(h, t);
if (ret == UJ_ERR_RETRY_LATER) {
// do not bother with the rest of time quantum if we're already stuck
ret = UJ_ERR_NONE;
break;
}
died = (t->pc == UJ_PC_DONE);
if (died) {
break;
}
if (ret != UJ_ERR_NONE) {
break;
}
}
This code in 47s again:
for (i = UJ_THREAD_QUANTUM+1; i > 0; --i) {
ret = ujThreadPrvInstr(h, t);
if (ret == UJ_ERR_RETRY_LATER) {
// do not bother with the rest of time quantum if we're already stuck
ret = UJ_ERR_NONE;
break;
}
died = (t->pc == UJ_PC_DONE);
if (died) {
break;
}
if (ret != UJ_ERR_NONE) {
break;
}
}
Thinking that I perhaps misunderstood some internal workings, I varied the value of UJ_THREAD_QUANTUM
(which is 10 by default) and post/predecrement counters but eventually discovered that it appears that whether I use >= 0
or > 0
is the deciding factor.
Can anybody explain why this is?
Upvotes: 1
Views: 264
Reputation: 52602
Forget everything that you read about loops, post increment, counting down to zero, and so on. This isn't even micro-optimisation, it is nano-optimisation. The only way it has any effect on the speed of your code is if you make a code that actually changes what the loop does. That is if by playing around with your loop you introduced bugs.
Especially in a case like this one, where you are playing around with threads - all quite expensive operations. What makes you think that it matters even one bit how you change your variables? Changing i is a matter of a nanosecond or less. How on earth will this have any effect on code that runs for 43 seconds unless you do it tens of billions of times?
For your loops, use code that is correct, and that is readable.
Upvotes: 0
Reputation: 1399
UInt8 ret, i;
means i >= 0
is always true. But i > 0
has to be evaluated.
Upvotes: 3