加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 09:21:57 所属栏目:百科 来源:网络整理
导读:我正在运行x86,我想看到我的机器上无序执行导致的错误.我尝试写一个,based off this wiki article,但我总是看到“x的值是33”: #includestdio.h#includepthread.h#include sys/types.hint x,f;void *handler(void *ptr) { while (f == 0); // Expectation:
我正在运行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?

如果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进行优化的情况下编译时,您的程序就相当于

_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/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读