关注
假设一台计算机配备两个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-05 11:43
门头沟学院 机械类 点赞 评论 收藏
转发
牛客热帖
正在热议
# 牛客帮帮团来啦!有问必答 #
382157次浏览 7620人参与
# 应届生初入职场,求建议 #
21939次浏览 537人参与
# 晒一晒我的offer #
2799570次浏览 49735人参与
# 在国企工作的人,躺平了吗? #
71605次浏览 868人参与
# 简历中的项目经历要怎么写 #
378239次浏览 6360人参与
# 非技术岗薪资爆料 #
6895次浏览 135人参与
# 你更愿意参加线上面试还是线下面试? #
6464次浏览 90人参与
# 非技术薪资爆料 #
63691次浏览 954人参与
# 华为求职进展汇总 #
438718次浏览 4411人参与
# 第一次面试 #
15688次浏览 239人参与
# 租房前辈的忠告 #
20747次浏览 1647人参与
# 应届生应该先就业还是先择业 #
12091次浏览 114人参与
# 安利/避雷我的岗位 #
122262次浏览 2752人参与
# 来聊聊机械薪资天花板是哪家 #
20773次浏览 165人参与
# 机械人怎么评价今年的华为 #
53981次浏览 442人参与
# 谈薪时HR压价该怎么应对 #
33019次浏览 204人参与
# 通信硬件薪资爆料 #
145043次浏览 1078人参与
# 毕业租房也有小确幸 #
19800次浏览 1249人参与
# 数据人offer决赛圈怎么选 #
36611次浏览 658人参与
# 正在实习的你,有转正机会吗? #
83224次浏览 865人参与