ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

多线程之程序的局部性原理和伪共享问题

2020-05-11 21:53:54  阅读:565  来源: 互联网

标签:缓存 cache 线程 内存 共享 多线程 局部性 cpu


程序的局部性原理

存储结构

在说局部性原理的时候,先来了解一下计算机的存储结构,设计到计算机组成结构的一些知识,计算机的存储结构,主要分以下几层,其中的磁盘跟本文无关。就暂且不提

  • 内存:一般也叫主存,存储的是程序运行所需要的数据,操作指令,中间结果和最终结果等。cpu就是从内存中调取数据进运算器执行,然后控制器发出控制信号
  • 高速缓存:也叫cache,位于cpu和内存之间,容量小,读写速度远远高于内存,接近cpu。一般和cpu集成在一起。主要为了解决内存和cpu内存不匹配的问题,cache从内存中取值是以缓存行为单位来取的。
  • 寄存器:寄存器是cpu内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。

局部性原理

通过上面的简单介绍,可以知道,在内存和cpu之间有一道cache,cpu取值是先看cache中有没有,如果有就从cache中拿,没有再访问主存。并且cache读取数据是并不是一个一个数据来读的,而是将目标数据所在的内存区域的一个缓存行大小一起读,作为一个缓存行,然后复制存进缓存的。总结一下就是:缓存行是主存和cache数据交换的单位。为什么要这么设计呢。程序的局部性原理认为:

CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中

时间局部性:程序有在一段时间内多次访问同一个数据块的倾向

空间局部性:程序往往有访问一个聚集空间的数据块的倾向

通俗来说呢就是,你对一个数据进行访问的时候,cpu认为,这个数据附近的数据部分也有非常有可能被访问,于是缓存就会直接把这个数据附近的数据也一起放到缓存中,节省cpu再到内存找的性能开销。举个例子:数组。数组的存储位置是连续的,但是我们一般在编程的时候,很少会单独的去访问数组的单个元素,就像我们平时写代码一样,数组都是用for循环去遍历,如果不把数组的的元素连续区域放进cache中,那cpu每循环一次,都要去内存中取值,效率较低。但是如果根据局部性原理,把这个数组的这块某块区域的大小都放进cache中,那cpu每次遍历只需要直接从高速缓存中取值。效率就会大大的提高。例如像这样

long a,b,c,d;

这个时候当cpu访问变量a的时候,如果a在缓存中没有,并且缓存行的大小为32字节,那么这个时候,abcd都会作为一个缓存行存进缓存中。因为cpu认为,bcd变量在后续的指令执行中非常有可能用到。

局部性原理并不是定理,而是一种经验的规律的总结,是计算机科学家在研究程序的运行过程发现的规律的总结,因此提出的提高效率的一种解决办法,目前很多的cpu都采用了这种方式。

伪共享

在多线程的环境中,伪共享的问题就是由于上面所说的程序的局部性原理导致的。从上面知道,cpu和主存之间隔着一个缓存,而缓存存值又是以缓存行作为单位的,cpu对值的修改也是以缓存行为单位的。由于程序的局部性原理,cpu从缓存中读取数据都是按缓存行来读的,一个缓存行可能是32个字节,也可能是64个字节等等,不同的cpu设计会有不同的大小。假设有x变量和y变量是在同一行被cpu读到,但是此时同时有两个线程,线程1对x进行操作,线程2对y进行操作。虽然他们读取的变量都不一样,由于这两个变量是在同一行。那么如果此时线程1对x的变量值进行了修改,由于缓存一致性协议,就要通知线程2 x的值被改了需要重新到主存中读取,这样就不是真正的共享。而这样反复的读取主存,就会无意中影响彼此的性能, 这就是线程间的伪共享问题。

如何解决伪共享问题

解决伪共享问题有一个很好的思路就是缓存对齐或者说缓存填充,例如有这样的一段代码,假设缓存行大小为64个字节。

 volatile long  value  = 0;
long p1,p2,p3,p4,p5,p6,p7;
long value2 = 2

只需要像这样,value和其他7个变量就会被放到同一个缓存行,value2又会被放到另一个缓存行中么,这样的话,对这个缓存行中的数据value和Value2读写就不会产生伪共享问题,因为他们是在不同的缓存行,这是一种用空间换时间的方式

在jdk1.8之后有一个注解,@sun.misc.centened.将这个注解放在变量上,会自动填充缓存行。但是这个注解要对jvm参数进行一些配置才会生效

标签:缓存,cache,线程,内存,共享,多线程,局部性,cpu
来源: https://www.cnblogs.com/blackmlik/p/12872458.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有