`

内存栅栏和内存对齐

 
阅读更多



 
Cache 一致性问题
单核 Cache 中每个 Cache line 有2个标志:dirty 和 valid 标志,它们很好的描述了 Cache 和 Memory 之间的数据关系(数据是否有效,数据是否被修改),而在多核处理器中,多个核会共享一些数据。



 
只有 Core 0 访问变量 x,它的 Cache line 数据和内存中的数据一致,数据只存在于本 Cache 中。



 
3个 Core 都访问变量 x,它们对应的 Cache line 数据和内存中的数据一致,数据存在于很多 Cache 中。



 

Core 0 修改了x的值之后,这个 Cache line 数据被修改了,和内存中的数据不一致,数据只存在于本 Cache 中。其他 Core 对应的 Cache line 数据无效。



 
内存栅栏
简单来说,内存栅栏(Memory Barrier)就是从本地或工作内存到主存之间的拷贝动作。


 
仅当写操作线程先跨越内存栅栏而读线程后跨越内存栅栏的情况下,写操作线程所做的变更才对其他线程可见。关键字 synchronized 和 volatile 都强制规定了所有的变更必须全局可见,该特性有助于跨越内存边界动作的发生,无论是有意为之还是无心插柳。
在程序运行过程中,所有的变更会先在寄存器或本地 cache 中完成,然后才会被拷贝到主存以跨越内存栅栏。此种跨越序列或顺序称为 happens-before。
写操作必须要 happens-before 读操作,即写线程需要在所有读线程跨越内存栅栏之前完成自己的跨越动作,其所做的变更才能对其他线程可见。


内存对齐
为何要内存对齐?
1. 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2. 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。



 
这是普通程序员心目中的内存印象,由一个个的字节组成,而 CPU 并不是这么看待的。


 
CPU 把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此 CPU 在读取内存时是一块一块进行读取的。块大小成为 memory accessgranularity(粒度)本人把它翻译为"内存读取粒度"。
假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:
1. 数据从0字节开始



 
2. 数据从1字节开始
再次假设内存读取粒度为4。



 
当该数据是从0字节开始时,CPU 只需读取内存一次即可把这4字节的数据完全读取到寄存器中。
当该数据是从1字节开始时,问题变的有些复杂,此时该 int 型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。

此时 CPU 先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了 CPU 性能。
这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分 CPU 肯干,其他一部分 CPU 遇到未对齐边界就直接*罢*工*了。

 

  • 大小: 10.1 KB
  • 大小: 7.8 KB
  • 大小: 3.8 KB
  • 大小: 4.7 KB
  • 大小: 62.3 KB
  • 大小: 22.4 KB
  • 大小: 22.2 KB
  • 大小: 20.7 KB
  • 大小: 19.6 KB
分享到:
评论

相关推荐

    Linux内存栅栏概述

    Linux内存栅栏概述 Linux内存栅栏概述 Linux内存栅栏概述

    内存栅栏和volatile关键字1

    4. { 7. } 1.编译器,CLR或CPU可能会为了性能重新为程序的指令进排序,例如可能 2.编译器,CLR或CPU可能会为变量 的赋值采缓存策略,这样这些

    深入多线程之:内存栅栏与volatile关键字的使用分析

    本篇文章对内存栅栏与volatile关键字的使用进行了详细的分析介绍,需要的朋友参考下

    栅栏解密和W型栅栏解密.py

    栅栏密码加密/解密算法传统型的栅栏密码加密/解密算法的变种,称为W型。网站有在线脚本,但在线下比赛时,会用到此脚本,自动分栏,比对结果

    栅栏密码加密解密工具

    栅栏密码加密解密工具

    栅栏桌面(fences)

    栅栏桌面-中文版(fences)是著名的Stardock公司推出的一款软件,用来分类和组织桌面上的图标一款软件。它可以将不同的图标放到不同的“容器”当中,你还可以移动和拉伸这个“容器”。这样将图标分类以后,你的桌面...

    栅栏密码zhala.py

    栅栏密码解密脚本

    栅栏加密算法实现c++实现

    栅栏加密代码的c++实现写的简单比较容易看也很容易学习

    矿用防爆柴油机排气栅栏结构研究

    防爆柴油机排气栅栏是用来熄灭排气系统中易燃气体,降低排气温度的安全装置,但是排气栅栏的安装,却增加了排气系统的阻力,从而影响防爆柴油机的动力性和经济性。文章利用UG软件建立了防爆柴油机排气栅栏的三维几何模型...

    栅栏密码加解密.py

    栅栏密码解密脚本

    栅栏密码Python代码

    栅栏密码Python代码,简单易懂。栅栏密码,就是把要加密的明文分成N个一组,然后把每组的第i个字连起来,形成一段无规律的话,一般比较常见的是2栏的棚栏密码。网络安全大赛必备。

    CAD铁栅栏园艺

    autocad2007 教程文档,铁栅栏模板,可用此直接制作铁艺栅栏

    矿用防爆柴油机栅栏式排气阻火器结构优化

    采用FLUENT软件对栅栏式排气阻火器的二维模型进行数值模拟,分析阻火器的阻火层厚度、栅栏间隙对淬熄距离和压力损失的影响。对模拟结果进行回归分析,得到了优化目标的回归模型;采用线性加权法合并淬熄距离和压力损失...

    汇编课设栅栏线代码

    汇编课设栅栏线代码

    栅栏密码加密加密工具

    栅栏密码加密加密工具,下载后无需安装直接打开即可使用

    栅栏爆破.py

    用于爆破栅栏密码。输入密文,讲输出不同长度间隔的明文

    栅栏密码加密解密

    栅栏密码加密解密,26栏以上通过测试,不必整除栏数,可以任意加密解密。 MV 开源设计工作室

    栅栏桌面Fences1.0简体中文版.rar

    右键单击栅栏选择"删除栅栏"可以删除一个栅栏。快捷提示:为了使您的桌面不出现混乱, 双击桌面可以快速隐藏所有图标。再次双击桌面显示所有隐藏图标。按住键盘的WINDOWS图标键然后再按"D"键可以快速显示桌面。再次...

Global site tag (gtag.js) - Google Analytics