avr-gcc:循环 >= 比 > 检查快

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

我的代码有些地方不明白。 我正在使用 avr-gcc 并优化我的代码以提高速度。我读过有关循环、倒数和 post/pre(递减)递减、与 0 的比较并发现了一些奇怪的东西。

此代码运行 47 秒:

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);

这段代码用了 43 秒:

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;
    }
}

这段代码又用了 47 秒:

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;
    }
}

考虑到我可能误解了一些内部工作原理,我改变了 UJ_THREAD_QUANTUM(默认情况下为 10)和 post/pre 递减计数器的值,但最终发现我是否使用 >= 0> 0是决定因素。

谁能解释这是为什么?

UInt8 ret, i;

表示 i >= 0 始终为真。但是i > 0还得评价

忘掉你读到的关于循环、post增量、倒数到零等等的一切。这甚至不是微优化,而是纳米优化。它对代码速度产生 any 影响的唯一方法是,如果您编写的代码实际上 改变 循环的作用。也就是说,如果通过循环播放你引入了错误。

尤其是在这种情况下,您正在使用线程 - 所有操作都非常昂贵。是什么让您认为改变变量的方式很重要?改变 i 是纳秒或更短的时间。除非您执行数百亿次,否则这对运行 43 秒的代码到底有何影响?

对于您的循环,请使用正确 且可读的代码。