关注
假设一台计算机配备两个CPU,在每个CPU中,cache 按地址被分成了两块 cache banks,分别是cache bank0 和 cache bank1。
举个理想的内存访问指令顺序例子:
1,CPU0往cache address 0×12345000 写入一个数字 1。因为address 0×12345000是偶数,所以值被写入 bank0.
2,CPU1读取 bank0 address 0×12345000 的值,即数字1。
3,CPU0往 cache 地址 0×12345100 写入一个数字 2。因为address 0×12345100是奇数,所以值被写入 bank1.
4,CPU1读取 bank1 address 0×12345100 的值,即数字2。
重排序后的内存访问指令顺序:
1,CPU0 准备往 bank0 address 0×12345000 写入数字 1。
2,CPU0检查 bank0 的可用性。发现 bank0 处于 busy 状态。
3,CPU0 为了防止 cache等待,发挥最大效能,将内存访问指令重排序。即先执行后面的 bank1 address 0×12345100 数字2的写入请求。
4,CPU0检查 bank1 可用性,发现bank1处于 idle 状态。
5,CPU0 将数字2写入 bank 1 address 0×12345100。
6,CPU1来读取 0×12345000,未读到 数字1,出错。
7,CPU0 继续检查 bank0 的可用性,发现这次bank0 可用了,然后将数字1写入 0×12345000。
8,CPU1 读取 0×12345100,读到数字2,正确。
可以看到第 3 步发生了指令重排序,并导致第 6步读到错误的数据。通过对指令重排,CPU可以获得更快地响应速度。重排序是为了优化性能,但是不管怎么重排序,单线程下程序的执行结果不能被改变。
内存屏障是用来防止CPU出现指令重排序的利器之一,一般在Java中,我们可以使用volatile来修饰变量,volatile底层就是使用到了内存屏障。
内存屏障会提供3个功能:
1.在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2.它会强制将对缓存的修改操作立即写入主存;
3. 如果是写操作,它会导致其他CPU中对应的缓存行无效。
查看原帖
点赞 评论
相关推荐
点赞 评论 收藏
分享
03-11 10:41
中国海洋大学 后端工程师 点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# AI替代不了什么? #
986次浏览 34人参与
# 发工资后,你做的第一件事是什么 #
100210次浏览 332人参与
# 厦门银行科技岗值不值得投 #
16457次浏览 404人参与
# 烂工作和没工作哪个更痛苦? #
960次浏览 34人参与
# 牛油的搬砖plog #
189111次浏览 1267人参与
# 学历VS实习,哪个更重要? #
7404次浏览 119人参与
# 工作上你捅过哪些篓子? #
69160次浏览 333人参与
# 产品人求职现状 #
361144次浏览 2601人参与
# 一人分享一道面试手撕题 #
113186次浏览 2779人参与
# 春招至今,你收到几个面试了? #
3630次浏览 24人参与
# uu们,春招你还来吗? #
68922次浏览 906人参与
# 面试中,你被问过哪些奇葩问题? #
99157次浏览 1413人参与
# 面试紧张时你会有什么表现? #
35576次浏览 241人参与
# 实习生应该准时下班吗 #
349183次浏览 1752人参与
# 你的实习什么时候入职 #
368114次浏览 2367人参与
# 牛友的志愿填报指南 #
63841次浏览 491人参与
# 关于春招你都做了哪些准备? #
145851次浏览 769人参与
# 机械校招之路总结 #
120248次浏览 2083人参与
# 90后北漂现状 #
36304次浏览 215人参与
# 网申一定要掌握的小技巧 #
20696次浏览 87人参与
# 机械人,签完三方你在忙什么? #
84287次浏览 267人参与
