【发布时间】:2019-04-03 11:19:54
【问题描述】:
来自ISO/IEC 9899:201x 部分5.1.2.3 程序执行:
2 访问易失性对象,修改对象,修改文件, 或调用执行任何这些操作的函数都是所有方面 效果,即执行状态的变化 环境。表达式的评估通常包括 价值计算和副作用的开始。价值计算 对于左值表达式,包括确定 指定对象。
因此,访问(读\写)一个 volatile 被称为副作用。 让我们继续:
4 在抽象机中,所有表达式都按指定计算 由语义。 实际的实现不需要评估部分 一个表达式,如果它可以推断出它的值没有被使用并且没有 产生了所需的副作用(包括任何由调用 函数或访问 volatile 对象)。
因此,如果我读取了 volatile(这是一种副作用),但对读取的获取值不做任何事情,则实际上不需要这种访问并且可以进行优化。
好的,还有:
6 对一致性实现的最低要求是:
对 volatile 对象的访问严格按照 抽象机的规则。
在程序终止时,所有数据 写入文件应与执行的结果相同 根据抽象语义的程序会产生。
交互设备的输入和输出动态应发生 如 7.21.3 中所述。这些要求的目的是 无缓冲或行缓冲的输出会尽快出现,以 确保提示消息实际出现在程序之前 等待输入。这是程序的可观察行为。
所以,据我了解,第 4 节是抽象机的规则,而6 节说需要严格按照抽象机规则评估 volatiles (第 4 节是)。因此可以优化读取访问(无需进一步使用获取的值)。
那么,看看这段代码:
volatile int *timer_reg = REGISTER_ADDRESS_CONST;
while (*timer_reg == 0) {/*empty loop*/}
此代码会阻止执行,直到硬件在timer_reg 指向的地址处产生一个位。该寄存器充当一种定时器,配置为在经过一定时间后升高位。当计时器结束时,忙等待结束并继续执行。
现在,可以优化这个while 循环吗?我已经在网上使用许多具有不同优化级别的编译器进行了尝试,但似乎没有。
我在这里缺少什么吗?据我了解,标准明确表示可以对其进行优化。
编辑:我的意思是,由于 while 循环是空的,编译器可能会认为获取的 volatile 值是不需要的。
【问题讨论】:
-
您正在使用获取的值。
-
@Mat 我已经编辑了问题
-
while循环的主体是空的,但整个循环却不是。 -
无法优化可观察行为,访问 volatile 限定类型的对象是可观察行为的一部分(尽管构成对 volatile 限定类型对象的访问是实现定义的)。跨度>
标签: c optimization language-lawyer volatile