返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #85533同步于 2015/1/31
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
多核cpu怎么保证同时访问内存中的数据的一致性
xurongfei
2015/1/31镜像同步13 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
如果在CPU这个层次,CPU有缓存,不同的核之间可能共享不同等级的缓存。硬件有一定的协议来保证缓存的一致性。
比如,一种策略是:每个页总会被某个核“拥有”。只有“拥有”一个页的时候可以写,其他时间可以读。如果另一个核想要写,首先会抢走这个页的所有权,抢的过程中会更新一些缓存的内容。抢到了以后就可以写了,原来的核再写的话,可以再把所有权“抢”回来。这样,如果一个页总被一个核写,性能很好;但是如果被多个核一起写的话,性能就不太好了。
在C语言的层次,C11之前从来没有提到“多线程”,所以在C11之前(如C89,C99)中使用多线程,是“未定义行为”。C语言并没有规定多线程的执行结果是什么样的,可能什么也不发生,也可能机器冒烟。具体的C语言实现(包括编译器、操作系统、标准库等一起完成)可以定义私有的接口(比如POSIX,需要操作系统、编译器、标准库一起实现),定义一些行为,但是不可移植的(比如用POSIX线程写的程序在Windows上也许不能用)。
C11提供了原子内存操作,包括原子读、写、以及一步完成的“读+改+写”操作,比如cmpxchg,fetch_add等。还有一系列多线程、锁、条件等标准同步机制。还有一个“memory model”,规定了多个线程对一个内存位置进行读写的时候可以看到什么样的值(注意因为cache等原因,一个线程写的东西,别的线程不是“立即”可以看到。但是有一些机制,如fence,如release-acquire关系等,可以保证一些可见性。正是memory model使得多线程的程序变得“有意义”。
关于memory model。推荐Hans Boehm的论文Foundations of the C++ Concurrency Memory Model http://www.hpl.hp.com/techreports/2008/HPL-2008-56.pdf