我想为 Atmel AVR 微 Controller 编写 C 代码固件。我将使用 GCC 编译它。此外,我想启用编译器优化(-Os
或 -O2
),因为我认为没有理由不启用它们,它们可能会更快地生成更好的汇编方式而不是手动编写汇编。
但是我想要一小段没有优化的代码。我想延迟某个函数的执行,因此我想写一个什么都不做的循环来浪费一些时间。无需精确,稍等片刻即可。
/* How to NOT optimize this, while optimizing other code? */
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i);
}
由于 AVR 中的内存访问速度很慢,我希望将 i
和 j
保存在 CPU 寄存器中。
更新:我刚找到 util/delay.h和 util/delay_basic.h来自 AVR Libc .尽管大多数时候使用这些函数可能是更好的主意,但这个问题仍然有效且有趣。
相关问题:
最佳答案
我在点击来自 dmckee's answer 的链接后得出了这个答案。 , 但它采用了与他/她的回答不同的方法。
Function Attributes GCC 的文档提到:
noinline
This function attribute prevents a function from being considered for inlining. If the function does not have side-effects, there are optimizations other than inlining that causes function calls to be optimized away, although the function call is live. To keep such calls from being optimized away, putasm ("");
这给了我一个有趣的想法......我没有在内部循环中添加一条 nop
指令,而是尝试在其中添加一个空的汇编代码,如下所示:
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i)
asm("");
}
成功了!该循环尚未优化,也没有插入额外的 nop
指令。
此外,如果你使用volatile
,gcc会将那些变量存储在RAM中,并添加一堆ldd
和std
来复制它们到临时寄存器。另一方面,这种方法不使用 volatile
并且不会产生此类开销。
更新:如果您使用-ansi
或-std
编译代码,您必须替换asm
带有 __asm__
的关键字,如 described in GCC documentation .
此外,如果您的 assembly statement must execute where we put it, (i.e. must not be moved out of a loop as an optimization) 也可以使用 __asm__ __volatile__("")
.
关于c - 如何防止 GCC 优化繁忙的等待循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23210361/