8

我正在使用 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.7with-o3和 ofast 优化级别进行了同样的尝试。在这种情况下,延迟似乎有效。

4

1 回答 1

20

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

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

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

这些优化规则都符合 C 标准中所写的内容(参见参考注释)。

此外,如果您想要延迟,请使用专门的功能(例如:OS API),它们是可靠的并且不消耗 CPU,这与您的自旋延迟不同。

于 2015-05-13T07:26:37.753 回答