受限是 volatile 的对立面吗?

Dav*_*542 2 c x86 assembly volatile restrict-qualifier

我可以使用volatile类似以下的内容,其中的值可能会被外部函数/信号/等修改:

volatile int exit = 0;
while (!exit)
{
    /* something */
}
Run Code Online (Sandbox Code Playgroud)

并且编译器/程序集不会缓存该值。另一方面,使用restrict关键字,我可以告诉编译器一个变量没有别名/只在当前范围内被引用一次,编译器可以尝试优化它:

void update_res (int *a , int *b, int * restrict c ) {
    * a += * c;
    * b += * c;
}
Run Code Online (Sandbox Code Playgroud)

这是对两者的正确理解,它们基本上是彼此对立的吗?volatile说该变量可以在当前范围之外修改并restrict说它不能?对于使用这两个关键字的最基本示例,它将发出的汇编指令示例是什么?

Pet*_*des 5

它们并不是完全相反的。但是,是的,volatile给优化器一个硬约束,优化对对象的访问,同时restrict是对优化器关于别名的承诺/保证,所以从广义上讲,它们在优化器的自由方面以相反的方向行事。(当然,通常只在优化构建中重要。)

restrict是完全可选的,只允许额外的性能。 volatile sig_atomic_t信号处理程序和主程序之间的通信或设备驱动程序之间的通信可能是“需要的”。对于任何其他用途,_Atomic通常是更好的选择。除此之外volatile,正常代码的正确性也不需要。(_Atomic具有类似的效果,尤其是对于故意不优化原子的当前编译器。)对于没有信号处理程序的单线程代码的正确性,volatile也不_Atomic需要,无论函数调用系列有多复杂,或任何数量的全局变量持有指向其他变量的指针。as-if 规则已经要求编译器制作 asm 以提供可观察的结果相当于一次单步执行 C 抽象机 1 行。(内存内容不是可观察的结果;这就是非原子对象上的数据竞争是未定义行为的原因。)


volatile意味着每个 C 变量读取(左值到右值转换)和写入(赋值)都必须成为 asm 加载和存储。实际上,是的,这意味着对于异步更改的事物(例如 MMIO 设备地址)或将自己_Atomic intmemory_order_relaxed. (何时将 volatile 与多线程一起使用? - 基本上从不在 C11 / C++11 中使用。)

volatile 表示可以在当前范围之外修改变量

这取决于你的意思。Volatile 远比这强得多,并且可以安全地在当前作用域内对其进行异步修改。

从此范围调用的函数修改全局exitvar已经是安全的;如果一个函数没有被内联,编译器通常必须假设每个全局变量都可以被修改,对于从全局指针(转义分析)或在这个翻译单元中调用修改文件范围静态的函数可能访问的所有内容都是一样的变量。

就像我说的,你可以将它用于多线程,但不要。C11_Atomic是标准化的,可用于编写编译为相同 asm 的代码,但对隐含和未隐含的内容有更多保证。(特别是订购wrt。其他操作。)


它们在手写 asm 中没有等价物,因为源代码和机器代码 asm 之间没有优化器。

在 C 编译器输出中,如果在禁用优化的情况下进行编译,您将不会注意到差异。 (好吧,volatile多次阅读相同的表达方式可能略有不同。)

在禁用优化的情况下编译会使 asm 变得无趣,其中每个对象都被视为volatile启用一致的调试。正如多线程程序卡在优化模式但在 -O0正常运行所示,通过使变量volatile变得简单而允许的优化非只有在启用优化的情况下才能完成。另请参阅有关具有中断的单核微控制器的相同问题的问答

*对于使用这两个关键字的最基本示例,它会发出什么汇编指令的示例?

https://godbolt.org/ 上使用 gcc10自己尝试一下-O3。你已经有了一个有用的测试用例restrict;它应该让编译器加载*c一次。

或者,如果您进行搜索,Ciro Santilli 已经分析了您在 2015 年询问的确切功能,在一个超过 150 票的回答中。我通过搜索找到它site:stackoverflow.com optimize restrict,作为第三次点击。

C99 'restrict' 关键字的实际用法?显示您的确切情况,包括带/不带限制的 asm 输出,以及对该 asm 的分析/讨论。


归档时间:

查看次数:

187 次

最近记录:

5 年,3 月 前