cpu cache的魔法
来源:互联网 发布:厦门大学团委知乎 编辑:程序博客网 时间:2024/04/24 11:47
首先简单了解一下什么是cpu cache这里推荐一篇文章吧,说的很详细。
关于cpu cache:点击打开链接
接下来我们看一些程序片段。
一眼看上去,程序没有任何问题,线程指之间共享的变量也加了锁,程序应该1s后打印run thread1,然后退出.
gcc main.cpp -O -pthread -g -o main执行以上命令编译,一定要加-O 开启编译器优化,然后执行./main后发现程序并没有按我们想象的那样1s后退出,而是陷入了一个死循环,当我们给flag加上volatile关键字是程序就如预期的那样。
volatile的特殊性在哪里,它是如何“防止”了线程不缓存共享变量的?常见的说法是使用volatile关键字之后,读取数据一定从内存中读取。实际上volatile关键字防止了编绎器优化,所以对于变量不会被放到寄存器里,或者被优化掉。但是volatile并不能防止CPU从Cache中读取数据。
所谓的“缓存”到底是什么,CPU内部有寄存器,有各级Cache,L1,L2,L3。我们来考虑下到底怎样才会出现线程共享变量被放到CPU的寄存器或者各级Cache的情况,volatile阻止了编绎器把变量放到寄存器里,那么对线程共享变量的读取即直接的内存访问。
CPU Cache放的正是内存的数据,而现代CPU有多核,通常来说每个核的L1, L2 Cache是不共享的,L3 Cache是共享的。那么问题就变成了:线程A修改了Cache中的内容,线程B是否会一直读取到的都是旧数据?既然Cache数据会不一致,那么自然要有个机制,让它们之间重回一致。经典的Cache一致性协议是MESI协议点击打开链接。
还有一个有趣的写法就是把注释打开,不用volatile程序也可正常运行,查了很多资料也没有结果,我的猜想是在调用sleep线程让出cpu使用权挂起,当cpu再次分配时间片给线程后,此时线程重新从内存中读取了flag的值,当然这只是我的猜想,很有可能是错的,希望哪位大神可以给我解惑。
由此看来,我们在多线程开发中不仅仅是保证共享数据同一时刻只有一个线程访问那么简单,我们还要保证一个线程的改变对另一个线程的可见性。
0 0
- cpu cache的魔法
- 关于CPU的Cache
- CPU的cache基础知识
- 走进 CPU 的 Cache
- CPU的Cache
- CPU 的Cache 和Latency
- 多级CPU Cache的利用率
- CPU 的 cache 和 latency
- CPU的cache line原理
- CPU cache
- CPU cache
- cpu Cache
- CPU cache
- CPU Cache
- Cache (computing) && CPU Cache
- 用oprofile统计CPU cache的命中率
- 关于CPU CACHE工作机制的学习
- CPU的高速缓存(cache)处理
- CardView的基本使用
- 文本相似性检测算法
- Android实现点击通知栏后,先启动应用再打开目标Activity
- BZOJ 2724 [Violet 6]蒲公英 分块
- 170228
- cpu cache的魔法
- java 策略模式
- 《Java虚拟机原理图解》3、JVM运行时数据区
- 防止浏览器记住用户名及密码的简单实用方法
- C#后台不识别Insert
- 棋牌游戏效果
- Lvs之NAT、DR、TUN三种模式的应用配置案例
- caffe: layer & layers之区别
- 类似百度搜索框时时查询