并发闲聊–数据可见性


说到并发就离不开数据可见性问题,主要的原因是同一个数据在不同的cpu核心的cache上可能不同(单个cpu则没有这个问题),不同的编程语言有不同的保证数据一致性的规则,java的volatile变量能保证当前读能获得上一个写入的值不管是不是运行在同个cpu核心上,那么其在底层上又是如何保证的呢?cpu、内存、cache是如何协作的呢?在网上翻阅了很多文章,对整个过程有了一个简单的认识,当然我并不是从事硬件方面或底层开发的人员,所以有些地方可能理解会有一定的不准确,如觉得哪里有什么问题,可以知会一声 ^_^。下面先从 cache 和 cpu聊起吧:




Cache

由于现代CPU的处理速度和内存操作的速度差距非常大,甚至可以达到上万倍,如果cpu直接操作内存中的数据,那样会导致cpu大量的处理能力被闲置,所以现代cpu会将内存数据复制到cache中再对其进行操作,并在未来的某个时刻将cache中被修改的部分重写回内存中。

         下面来看下intel x86 Sandy Bridge架构的cache(其他CPU架构也使用相似技术以达到相同目的):(详细可以查看:CPU缓存刷新的误解

 


其中L1 和 L2 缓存为cpu单个核心私有的缓存,L3 缓存是同插槽的所有核心都共享的缓存。

L1缓存被分成独立的32K数据缓存和32K指令缓存,

L2缓存被设计为L1缓存与共享的L3缓存之间的缓冲。L2缓存大小为256K,主要作用是作为L1和L3之间的高效内存访问队列。L2缓存同时包含数据和指令。

L3缓存包括了在同一个槽上的所有L1和L2缓存中的数据。这种设计消耗了空间,但是可以拦截对L1和L2缓存的请求,减轻了各核心私有的L1和L2缓存的负担。

 

在本文就不谈论L1 L2 L3 Cache之间的关系,在下面的描述中都将它们看成一个整体。

 

Cpu操作内存是以64字节为单位的块(chunk)存取的,称为一个缓存行(cache line)。当你读一个特定的内存地址,该地址附近共64个字节的数据(整个缓存行)将从主存加载到缓存,所以当cpu想要访问同一个缓存行内的其它值的开销是很小的。Cache的读取更新等都是以缓存行为单位

 

内存中的一个块如何映射到Cache上的某个位置呢?当然方法可能有很多,通常cpu采用N-Way Set Associative模式,他的做法是把缓存等分成很多个组,每个组包含N个CacheLine,通过内存地址能确定该内存块会被会被放置到哪个组中,至于在组里面的第几个块就是不确定的。

直接看一个例子吧(16-Way SetAssociative)(这里假设缓存大小为4M):

 

在64位系统内的内存地址(64位):

00000000 00000000 00000000 00000000 0000000000000000 00000000 00000000

将落在哪个组中?

 

1.      首先,内存操作是按64位(6位的2进制可以表达)为一个单位来操作,所以内存地址的后6位是不会影响内存属于哪个缓存行的:

00000000 00000000 00000000 0000000000000000 00000000 00000000 0000000

 

2.      4M的16路的缓存可以分割为4096个组,其需要12个位来表示:

00000000 00000000 00000000 0000000000000000 00000000 000000000000000

 

所以在这个假设中(不同大小的cache会不一样),一个内存地址落在哪个缓存组中是由由低位数起的第7位到第18位决定的。

 

当确定了内存地址在哪个组后,当前内存地址究竟会在这个组里面的什么位置呢?这个是运行时决定的,所以当真正要在chache查询这个内存地址的数据时,需要对比同个组内的16路的内存地址(在硬件层面是很容易实现的),当要写入一个新的内存块而该组内又没有空的位置时,就需要就要驱逐一个chunk。

 

那么根据这个规则可以算出来:

1.      每隔  64字节(块大小) * 4096个组 = 262144字节(256k)  就会重新落到原来的缓存组中

2.      该cache最多可以  256k * 16路 = 4M的数据(废话ˇ_ˇ)

 

想了解更多关于cache以及cache命中等,可以参考 7个示例科普CPU Cache



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值