for 循环被忽略(优化?)
for loop being ignored (optimized?) out
我正在使用 for/while 循环在我的代码中实现延迟。延迟的持续时间在这里并不重要,尽管它大到足以引起注意。这是代码片段。
uint32_t i;
// Do something useful
for (i = 0; i < 50000000U; ++i)
{}
// Do something useful
我观察到的问题是这个 for 循环不会被执行。编译器可能会得到 ignored/optimized。但是,如果我用 volatile 限定循环计数器 i
,则 for 循环似乎会执行并且我确实注意到执行中所需的延迟。
这种行为似乎有点违反我对编译器优化的理解 with/without volatile 关键字。
即使循环计数器得到优化并存储在处理器寄存器中,计数器不应该仍然工作,也许延迟更小吗? (因为内存获取开销被取消了。)
我正在构建的平台是 Xtensa 处理器(由 Tensilica 提供),C 编译器是由 Tensilica 提供的,Xtensa C/C++ 编译器 运行 最高级别的优化。
我对 gcc 4.4.7
和 -o3
以及 ofast 优化级别进行了相同的尝试。在这种情况下延迟似乎有效。
这都是关于可观察到的行为。循环的唯一可观察到的行为是 i
在循环之后是 50000000U
。允许编译器对其进行优化,将其替换为i = 50000000U;
。此 i
分配也将被优化,因为 i
的值没有可观察到的结果。
volatile
关键字告诉编译器写入和读取 i
具有可观察到的行为,从而阻止其优化。
编译器也不会优化对无法访问代码的函数的调用。理论上,如果编译器可以访问整个 OS 代码,它可以优化除 volatile 变量之外的所有内容,这些变量通常用于硬件 IO 操作。
这些优化规则都符合C标准写的(参考文献注释)。
此外,如果您想要延迟,请使用专门的函数(例如:OS API),它们可靠且不会消耗 CPU,这与自旋不同像你一样延迟。
我正在使用 for/while 循环在我的代码中实现延迟。延迟的持续时间在这里并不重要,尽管它大到足以引起注意。这是代码片段。
uint32_t i;
// Do something useful
for (i = 0; i < 50000000U; ++i)
{}
// Do something useful
我观察到的问题是这个 for 循环不会被执行。编译器可能会得到 ignored/optimized。但是,如果我用 volatile 限定循环计数器 i
,则 for 循环似乎会执行并且我确实注意到执行中所需的延迟。
这种行为似乎有点违反我对编译器优化的理解 with/without volatile 关键字。
即使循环计数器得到优化并存储在处理器寄存器中,计数器不应该仍然工作,也许延迟更小吗? (因为内存获取开销被取消了。)
我正在构建的平台是 Xtensa 处理器(由 Tensilica 提供),C 编译器是由 Tensilica 提供的,Xtensa C/C++ 编译器 运行 最高级别的优化。
我对 gcc 4.4.7
和 -o3
以及 ofast 优化级别进行了相同的尝试。在这种情况下延迟似乎有效。
这都是关于可观察到的行为。循环的唯一可观察到的行为是 i
在循环之后是 50000000U
。允许编译器对其进行优化,将其替换为i = 50000000U;
。此 i
分配也将被优化,因为 i
的值没有可观察到的结果。
volatile
关键字告诉编译器写入和读取 i
具有可观察到的行为,从而阻止其优化。
编译器也不会优化对无法访问代码的函数的调用。理论上,如果编译器可以访问整个 OS 代码,它可以优化除 volatile 变量之外的所有内容,这些变量通常用于硬件 IO 操作。
这些优化规则都符合C标准写的(参考文献注释)。
此外,如果您想要延迟,请使用专门的函数(例如:OS API),它们可靠且不会消耗 CPU,这与自旋不同像你一样延迟。