简体   繁体   中英

avr-gcc: loop with >= faster than > check

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM