首页 > 编程语言 > 详细

多线程 - 内存屏障和cpu缓存

时间:2019-10-15 19:25:47      阅读:80      评论:0      收藏:0      [点我收藏+]

CPU性能优化 - 缓存

为了提高程序运行的性能,现代CPU在很多方面会对程序进行优化。CPU的处理速度是很快的,内存的速度次之,硬盘速度最慢。在cpu处理内存数据中,内存运行速度太慢,就会拖累cpu的速度。为了解决这样的问题,cpu设计了多级缓存策略。

CPU分为三级缓存: 每个CPU都有L1,L2 但是L3是多核公用的。

  • L1 Cache (一级缓存)是CPU第一层告诉缓存,分为数据缓存和指令缓存。一般服务器的CPU的L1缓存的容量通常在32-4096K
  • L2 Cache (二级缓存)由于L1高速缓存的容量限制,为了再次提高CPU的运算速度,在CPU外部放置一告诉存储器,即二级缓存。
  • L3 Cache (三级缓存) 都是内置的,它的作用是进一步降低内存延迟,同事提升大数据量计算时处理器的性能。具有较大L3缓存的处理器,能提供更有效的文件系统缓存行为及较短的消息和队列长度。一般多核共享一个L3缓存。

CPU查找数据的顺序为: CPU -> L1 -> L2 -> L3 -> 内存 -> 硬盘

缓存同步协议

因为每个CPU都有自己的缓存,容易导致一种情况就是 如果多个CPU的缓存(多CPU读取同样的数据进行缓存,进行不同运算后,写入内存中)中都有同样一份数据,那这个数据要如何处理呢?已谁的为准? 这个时候就需要一个缓存同步协议了!
MESI协议 规定每条缓存都有一个状态位,同时定义了一下四种状态:

  • 修改态 (Modified) 此缓存被修改过,内容与住内存不同,为此缓存专有
  • 专有态 (Exclusive) 此缓存与主内存一致,但是其他CPU中没有
  • 共享态 (Shared) 此缓存与住内存一致,但也出现在其他缓存中。
  • 无效态 (Invalid) 此缓存无效,需要从主内存中重新读取。

多处理器,单个CPU对缓存修改,需要通知其他CPU. 也就意味着,CPU需要控制自己的读写,还需要监听其他CPU发出的通知,从而保持最终一致性。

CPU性能优化 - 运行时指令重排序

例如如下代码是:
技术分享图片

指令重排:当CPU 写缓存 时发现缓存区被其他CPU占用,为了提高CPU处理性能,可能将后面的读缓存命令优先执行
指令重排序,遵循 as-if-serial语义。即指令重排序前后,程序执行的结果不能变化。对于数据有依赖的部分,不会进行重排序。

问题

1、CPU高速缓存的问题:
缓存中的数据与主内存的数据不是实时同步的,各个CPU间缓存的数据也不是实时同步的,在同一时间点,各个CPU所看到的的同一内存地址的数据可能是不一致的

2、CPU指令重排优化问题:
虽然遵循 as-if-serial语义,但是它是仅在单个CPU自己执行的情况下保证结果正确,多核多线程,指令逻辑无法分辨因果关联,可能出现乱序执行,导致程序结果出现错误。

内存屏障解决以上问题

写内存屏障(Store Memory Barrier):在指令后插入Store Barrier,能让写入缓存中最新数据更新写入主内存中,让其他线程可见。 强制写入主内存,这种显示调用,不会让CPU去进行指令重排序
读内存屏障(Load Memory Barrier):在指令后插入Load Barrier,可以让高速缓存中的数据失效,强制重新从住内存中加载数据。 也是不会让CPU去进行指令重排。

多线程 - 内存屏障和cpu缓存

原文:https://www.cnblogs.com/junjiedeng/p/11679596.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!