gpt4 book ai didi

c - GCC 中的订购保证

转载 作者:太空狗 更新时间:2023-10-29 17:23:35 26 4
gpt4 key购买 nike

我碰巧深入研究了 C 并进行了无锁编程。摆弄它 我想知道 gcc 能给我什么保证,即程序的执行方式与我写下的方式完全相同,并且在某个步骤中没有执行寄存器优化,也没有改变其顺序的操作。

据我目前的理解,它保证内存操作以完全相同的顺序发生,并且方法调用与它们自身和内存操作一起以相同的顺序发生。在这两者之间可能会发生重新排序。

可以使用 volatile 关键字关闭寄存器优化。

C 尤其是 gcc 是否暗示了任何额外的保证或极端情况?

最佳答案

编译器只需要不改变程序的含义即可。

程序的含义由其 C 语句的语义给出,例如 volatile 限定符是一种在语义级别具体化与外部代理交互的方式。
然而,volatile 本身在线程同步方面毫无用处,它仅具有本地 效果。

所以你应该只暗示 C 标准暗示的内容,如果标准没有给语句提供顺序语义也没有任何副作用,那么就没有。

为了优化一些代码,编译器必须证明优化不会改变含义。
这通常是一个困难的(甚至是不可判定的)问题,所以它只在简单的上下文中完成。

考虑

#include <stdio.h>

int simple(const int a, const int b)
{
int c = a + b; //3x Memory operation?
int d = c*c; //2x Memory operation?

return d+d; //Memory operation?

}

int main()
{
int a = 0; //Memory operation?
int b = 0; //Memory operation?

a = simple(2, 3); //Function call + Memory operation?
b = simple(3, 4); //Function call + Memory operation?

printf("%d %d\n", a, b); //Function call + 3x Memory operation?

return 0;
}

C 标准规定 a = simple(2, 3);b = simple(3, 4); 之前执行,因为表达式的结尾是一个序列点。

这是经过全面优化的 gcc 生成的代码

lea    0x18f0(%rip),%rcx        # 0x100403030, "%d %d\n"
mov $0x62,%r8d
mov $0x32,%edx
callq 0x100401110 <printf>

我使用的是 cygwin,所以 ABI 是 Windows 的。这相当于

printf("%d %d\n", 50, 98);

这是一个特别的例子,函数simplepure并且采用编译时常量表达式,所以结果在编译时已知时间。
这是 gcc 需要优化调用的证明


在编写无锁代码时,只要使用正确的语义(例如,volatile 将读写访问作为副作用用于仅出于优化目的)。

真正应该担心的是memory ordering正如我在评论中指出的那样。
C11 最终在其 memory model 中具体化了所有这些.

关于c - GCC 中的订购保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31470179/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com