- 主题:乱序执行的CPU怎么处理多线程中,共享变量有前后依赖的问题的?
底层是mesi外加上内存屏障可以保证。 mesi基本是cpu硬件层自带,软件层需要在引入store buffer和invlid queue后解决变量可见性,语言层封装就是类似cpp中的atomic操作。
【 在 wjhtingerx (ca6140) 的大作中提到: 】
: 比如:
: 线程1:
: b=2;
: a=1;
--
FROM 39.144.104.*
这好像是Memory Barriers: a Hardware View for Software Hackers中举的例子
具体解决办法就是加各种memory barrier ,详解的介绍可以看书籍
Is Parallel Programming Hard, And, If So, What Can You Do About It
中文版书籍名字叫深入理解并行编程 都是同一个作者
--
FROM 124.93.160.*
【 在 wjhtingerx 的大作中提到: 】
: 为啥增加d = b后,a更容易乱序?
: 我的疑问是,这种场景应该是很多的,但是实际开发中,知道这些的程序员其实很少的,为啥也没听说爆出啥大的问题呢
:
知道这个点不多是因为你的岗位接触的少。
如果你是一个嵌入式工程师,写过最简单的NOR FLASH驱动,就一定会遇到这种严格要求执行结果的case。因为一旦乱序,硬件就不work了。所以驱动代码中插入了很多barrier指令。
其他场景也很多,不一而足。写应用程序代码的一般不需要这个知识点。你写驱动代码或者操作系统内核代码就会时不时遇到。Linux里面有标准的read/write/read&write的barrier接口API。
增加d = b后更容易乱序是因为前面对b的操作更多需要更多的指令,既然需要更多的指令,系统在执行这些指令的时候就更容易对后面的指令乱序执行(等不及了,因为多流水线多发射的系统有空闲资源了)。
ARM里的dsb指令就是data sync barrier,保证之前的指令中和数据相关的指令都一定完成才会执行dsb后面和数据相关的指令。
所以就是我之前帖子里说的,你这个case,在b=2后面增加一个dsb,ARM系统里绝对就没问题了。
本中是做CPU架构研究和OS内核适配的,对这些浸淫已久....
--
修改:beanspower FROM 111.197.20.*
FROM 111.197.20.*
你看错了吧,chatgpt并没回答错误。
他区分了java里的volatile和c++里的volatile,而且没说volatile能解决所有的变量同步问题。
【 在 wjhtingerx 的大作中提到: 】
: 这里回答很多是错的,volatile只约束编译结果,跟CPU的乱序执行无关。
:
--
修改:z16166 FROM 61.48.130.*
FROM 61.48.130.*
【 在 wjhtingerx 的大作中提到: 】
: 这里回答很多是错的,volatile只约束编译结果,跟CPU的乱序执行无关。
:
这里chatGPT只提到了java应用层面的volatile,它说了能那估计就能了。因为编译器应该是在和这个指令后面增加了barrier指令。C的volatile是达不到这个效果的,必须自己显式的增加barrier指令。
不管是c,java还是c++,最底层的逻辑是一样的,都是同样的处理器架构和汇编要求。
--
FROM 111.197.20.*
【 在 wjhtingerx 的大作中提到: 】
: 为啥增加d = b后,a更容易乱序?
: 我的疑问是,这种场景应该是很多的,但是实际开发中,知道这些的程序员其实很少的,为啥也没听说爆出啥大的问题呢
:
另外,你不是在另一个帖子问以太网的问题吗。你看看以太网驱动,在最后设置descriptor的状态之前,一定有一个显式的barrier指令,就是为了解决乱序问题。,确保数据就绪才能设置“硬件发送”标志。
--
FROM 111.197.20.*
java的volatile是标准的使用Release-Require实现的内存屏障。
【 在 beanspower (豆能) 的大作中提到: 】
:
: 【 在 wjhtingerx 的大作中提到: 】
: : 这里回答很多是错的,volatile只约束编译结果,跟CPU的乱序执行无关。
: :
--
FROM 39.144.104.*
原子类型解决不了你的语义问题。这个问题归根到底是取决于你的目标和语义。假设你的语义就是b和a绑定的,即,a仅仅充当b的更新"标志",那么你的确需要手动保证ba的先后顺序,什么原子类型你都得强制顺序。治本是改用Rust,Option<T>
【 在 wjhtingerx 的大作中提到: 】
: 比如:线程1:b=2;a=1;线程2:while(a=1){c=b;}如果a和b乱序了,线程2执行就不对了。 ...
--
FROM 114.246.94.*
因为大多数程序员不写内核不写驱动。
另外这个问题在X86上要比各种RISC不那么严重一些。
【 在 wjhtingerx 的大作中提到: 】
: 为啥增加d = b后,a更容易乱序?
: 我的疑问是,这种场景应该是很多的,但是实际开发中,知道这些的程序员其实很少的,为啥也没听说爆出啥大的问题呢
--
FROM 183.156.54.*
如果不是特别性能敏感,数据依赖问题通通加锁。
这是最简单也是最常用的解决方案。
【 在 wjhtingerx 的大作中提到: 】
: 比如:
: 线程1:
: b=2;
: ...................
--来自微微水木3.5.14
--
FROM 183.193.49.*