for循环被忽略(优化?)out

时间:2015-05-13 07:16:15

标签: c compiler-optimization

我正在使用for / while循环来实现代码中的延迟。延迟的持续时间在这里并不重要,尽管它足够大而值得注意。这是代码段。

uint32_t i;

// Do something useful

for (i = 0; i < 50000000U; ++i)
{}

// Do something useful

我观察到的问题是这个for循环不会被执行。它可能会被编译器忽略/优化。但是,如果我通过volatile限定循环计数器i,则for循环似乎执行,并且我注意到执行中所需的延迟。

对于我对使用/不使用volatile关键字的编译器优化的理解,这种行为似乎有点违反直觉。

即使循环计数器得到优化并存储在处理器寄存器中,该计数器是否仍然有效,可能延迟较小? (因为内存提取开销已经完成了。)

我正在构建的平台是Xtensa处理器(由Tensilica提供),C编译器是由Tensilica提供的,Xtensa C / C ++编译器以最高级别的优化运行。

我使用gcc 4.4.7-o3以及广播优化级别尝试了相同的操作。在这种情况下,延迟似乎有效。

1 个答案:

答案 0 :(得分:15)

这完全是关于可观察的行为。循环的唯一可观察行为是循环后i50000000U。允许编译器对其进行优化并将其替换为i = 50000000U;。此i作业也将进行优化,因为i的值没有可观察到的后果。

volatile关键字告诉编译器写入和读取i具有可观察的行为,从而阻止其优化。

编译器也不会优化对无法访问代码的函数的调用。从理论上讲,如果编译器可以访问整个操作系统代码,它可以优化除易失性变量之外的所有内容,这些变量通常放在硬件IO操作上。

这些优化规则都符合C标准中的内容( cf。引用注释)。

此外,如果你想延迟,使用专门的功能(例如:OS API),它们是可靠的,不会消耗CPU,不像你的旋转延迟。