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?
UInt8 ret, i;
means i >= 0
is always true. But i > 0
has to be evaluated.