大佬教程收集整理的这篇文章主要介绍了简单的C程序来说明乱序执行?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_11@#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”?
内存重新排序与指令执行重新排序是分开的,因为即使有序cpu也使用存储缓冲区来避免在缓存未命中存储上停滞.
Out-of-order instruction execution: is commit order preserved?
Are loads and stores the only instructions that gets reordered?
如果x和f最终在不同的高速缓存行中,则有序ARM cpu上的C实现可以打印11或33.
我假设您编译时禁用了优化,因此您的编译器会有效地处理所有变量volatile,即volatilE int x,f.否则为while(f == 0); loop将编译为if(f == 0){infloop; },只检查一次. (非原子变量的数据竞争UB允许编译器从循环中提升负载,但必须始终完成易失性负载.https://electronics.stackexchange.com/questions/387181/mcu-programming-c-o2-optimization-breaks-while-loop#387478).
生成的asm / machine代码中的商店将以C源顺序显示.
您正在编译x86,它具有强大的内存模型:x86存储是发布存储,x86负载是获取负载.您没有获得顺序一致性,但您可以免费获得acq_rel. (对于未经优化的代码,即使您不要求它也会发生.)
因此,在没有针对x86进行优化的情况下编译时,您的程序就相当于
@H_403_11@_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程序来说明乱序执行?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。