gpt4 book ai didi

c - 简单的C程序来说明乱序执行?

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

我正在运行 x86,我想在我的机器上实际查看由乱序执行引起的错误。我试着写了一个,based off this wiki article ,但我总是看到“x 的值为 33”:

#include<stdio.h>
#include<pthread.h>
#include <sys/types.h>

int x, f;

void *handler(void *ptr) {
while (f == 0);
// Expectation: Sometimes, this should print 11 due to out-of-order exec
printf("value of x is %d \n", x);
return NULL;
}

int main() {
pthread_t thread1;
while(1) {
x = 11; f = 0;
pthread_create(&thread1, NULL, handler, NULL);
x = 33;
f = 1;
pthread_join(thread1, NULL);
}
return 0;
}

可以说明乱序执行错误的最简单的 c 程序是什么?为什么这有时不打印“x 的值为 11”?

最佳答案

您尝试创建的效果不依赖于乱序执行。这只是可以创建内存重新排序的事情之一。此外,现代 x86 会乱序执行,但会使用其内存顺序缓冲区来确保存储提交到 L1d/在程序顺序中变得全局可见。 (因为 x86 的内存模型只允许 StoreLoad 重新排序,而不允许 StoreStore。)

内存重新排序与指令执行重新排序是分开的,因为即使是有序的 CPU 也会使用存储缓冲区来避免在缓存未命中存储时停顿。

Out-of-order instruction execution: is commit order preserved?

Are loads and stores the only instructions that gets reordered?


如果 xf 在不同的缓存行中结束,则有序 ARM CPU 上的 C 实现可以打印 11 或 33。


我假设您在编译时禁用了优化,因此您的编译器会有效地处理所有变量 volatile,即 volatile int x,f。否则 while(f==0); 循环将编译为 if(f==0) { infloop; },只检查一次f。 (非原子变量的数据竞争 UB 允许编译器将负载提升到循环之外,但 volatile 负载必须始终完成。https://electronics.stackexchange.com/questions/387181/mcu-programming-c-o2-optimization-breaks-while-loop#387478)。

生成的 asm/机器代码中的存储将以 C 源代码顺序出现。

您正在为 x86 编译,它具有强大的内存模型:x86 存储是发布存储,x86 加载是获取加载。您不会获得顺序一致性,但可以免费获得 acq_rel。 (对于未优化的代码,即使您不要求它也会发生。)

因此,在没有针对 x86 进行优化的情况下编译时,您的程序等同于

_Atomic int x, f;

int main(){
...
pthread_create
atomic_store_explicit(&x, 33, memory_order_release);
atomic_store_explicit(&f, 1, memory_order_release);
...
}

对于负载端也是如此。 while(f==0){} 是 x86 上的获取负载,因此让读取端等待直到它看到非零 f 保证它也看到x==33.

但是如果你为像 ARM 或 PowerPC 这样的弱排序 ISA 编译,那里的 asm 级内存排序保证允许 StoreStore 和 LoadLoad 重新排序,所以你的程序有可能打印 11 如果编译时没有优化。

另见 https://preshing.com/20120930/weak-vs-strong-memory-models/

关于c - 简单的C程序来说明乱序执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52691544/

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