我正在使用 for/while 循环在我的代码中实现延迟。延迟的持续时间在这里并不重要,尽管它足够大而引人注目。这是代码片段。
uint32_t i;
// Do something useful
for (i = 0; i < 50000000U; ++i)
{}
// Do something useful
我观察到的问题是这个 for 循环不会被执行。它可能会被编译器忽略/优化。但是,如果我限定循环计数器i
通过 挥发性,for 循环似乎执行并且我确实注意到执行中所需的延迟。
对于我对使用/不使用 volatile 关键字的编译器优化的理解,这种行为似乎有点违反直觉。
即使循环计数器得到优化并存储在处理器寄存器中,计数器是否仍然应该工作,也许延迟更小? (因为内存获取开销被消除了。)
我构建的平台是 Xtensa 处理器(由 Tensilica 提供),C 编译器是 Tensilica 提供的,Xtensa C/C++ 编译器以最高级别的优化运行。
我尝试了同样的方法gcc 4.4.7
with -o3
和 ofast 优化级别。在这种情况下,延迟似乎有效。
这都是关于可观察的行为。循环唯一可观察到的行为是i
is 50000000U
循环之后。允许编译器对其进行优化并将其替换为i = 50000000U;
. This i
分配也会被优化掉,因为i
没有可观察到的后果。
The volatile
关键字告诉编译器写入和读取i
具有可观察的行为,从而阻止其优化。
编译器也不会优化对无法访问代码的函数的调用。理论上,如果编译器能够访问整个操作系统代码,它就可以优化除易失性变量之外的所有内容,这些变量通常放在硬件 IO 操作上。
这些优化规则都符合C标准中所写的(参见评论供参考).
另外,如果您想要延迟,请使用专门的函数(例如:操作系统 API),它们是可靠的并且不消耗 CPU,这与像您这样的旋转延迟不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)