博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Memory Barrier in Compiler and CPU
阅读量:7045 次
发布时间:2019-06-28

本文共 2784 字,大约阅读时间需要 9 分钟。

Memory barrier, is a type of barrier and a class of instruction which causes a CPU or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction.

之所以需要Memory barrier就是因为CPU Out-of-order execution 和 compiler reordering optimizations。

 

 

Compiler memory barrier

 
These barriers prevent a compiler from reordering instructions, they do not prevent reordering by CPU.
The GNU inline assembler statement
asm volatile("" ::: "memory");
 
or even
__asm__ __volatile__ ("" ::: "memory");
 
forbids GCC compiler to reorder read and write commands around it.
Intel ECC compiler uses "full compiler fence"
__memory_barrier()
 
intrinsics.
Microsoft Visual C++ Compiler:[8]
_ReadWriteBarrier()

 

Hardware memory barrier

 
Many architectures with SMP support have special hardware instruction for flushing reads and writes.
x86, x86-64
lfence (asm), void_mm_lfence(void)
sfence (asm), void_mm_sfence(void) [9]
mfence (asm), void_mm_mfence(void) [10]
ARMv7
dmb (asm)
对硬件memory barrier的更多理解

  1. 只有一个主体(CPU或DMA控制器)访问内存时,无论如何也不需要barrier;但如果有两个或更多主体访问内存,且其中有一个在观测另一个,就需要barrier了。
  2. IA32 CPU调用有lock前缀的指令,或者如xchg这样的指令,会导致其它的CPU也触发一定的动作来同步自己的Cache。CPU的#lock引脚链接到北桥芯片(North Bridge)的#lock引脚,当带lock前缀的执行执行时,北桥芯片会拉起#lock电平,从而锁住总线,直到该指令执行完毕再放开。 而总线加锁会自动invalidate所有CPU对 _该指令涉及的内存的Cache,因此barrier就能保证所有CPU的Cache一致性。
  3. lock前缀(或cpuid、xchg等指令)使得本CPU的Cache写入了内存,该写入动作也会引起别的CPU invalidate其Cache。IA32在每个CPU内部实现了Snoopying(BUS-Watching)技术,监视着总线上是否发生了写内存操作(由某个CPU或DMA控制器发出的),只要发生了,就invalidate相关的Cache line。 因此,只要lock前缀导致本CPU写内存,就必将导致所有CPU去invalidate其相关的Cache line。

两个地方可能除外:

  • 如果采用write-through策略,则根本不存在缓存一致性问题(Linux对全部内存采用write-back策略);
  • TLB也是Cache,但它的一致性(至少在IA32上)不能通过Snooping技术解决,而是要发送INVALIDATE_TLB_VECTOR这个IPI给其它的CPU。

 

MESI协议

M: Modified,已修改

E: Exclusive,排他
S: Shared,共享
I: Invalid,无效

IA32 的CPU实现了MESI协议来保证Cache coherence。 CPU的总线监测单元,始终监视着总线上所有的内存写操作,以便随时调整自己的Cache状态。

-> Modified。 本CPU写,则直接写到Cache,不产生总线事物;其它CPU写,则不涉及本CPU的Cache,其它CPU读,则本CPU需要把Cache line中的数据提供给它,而不是让它去读内存。

-> Exclusive。只有本CPU有该内存的Cache,而且和内存一致。 本CPU的写操作会导致转到Modified状态。

-> Shared。 多个CPU都对该内存有Cache,而且内容一致。任何一个CPU写自己的这个Cache都必须通知其它的CPU。

-> Invalid。 一旦Cache line进入这个状态,CPU读数据就必须发出总线事物,从内存读。

 

DMA写策略

1. Write through策略。 这种情形比较简单。

-> 本CPU写内存,是write through的,因此无论什么时候DMA读内存,读到的都是正确数据。

-> DMA写内存,如果DMA要写的内存被本CPU缓存了,那么必须Invalidate这个Cache line。下次CPU读它,就
直接从内存读。

2. Write back策略。 这种情形相当复杂。

-> DMA读内存。被本CPU总线监视单元发现,而且本地Cache中有Modified数据,本CPU就截获DMA的内存读操作,

把自己Cache Line中的数据返回给它。

-> DMA写内存。而且所写的位置在本CPU的Cache中,这又分两种情况:

  • Cache Line状态未被CPU修改过(即cache和内存一致),那么invalidate该cache line。
  • Cache Line状态已经被修改过,又分2种情况:
    • DMA写操作会替换CPU Cache line所对应的整行内存数据,那么DMA写,CPU则invalidate自己的Cache Line。
    • DMA写操作只替换Cache Line对应的内存数据的一部分,那么CPU必须捕获DMA写操作的新数据(即DMA想把它写入内存的),用来更新Cache Line的相关部分。

转载于:https://www.cnblogs.com/whyandinside/archive/2012/06/24/2560099.html

你可能感兴趣的文章
没有PowerPoint2010的环境如何播放.PPTX文件
查看>>
Outlook 2010 中查看邮件头
查看>>
AWS - Cloudfront CDN 测试
查看>>
PXE+Kickstart详细版 【第一次编辑】
查看>>
云平台与云主机选择的经验和建议
查看>>
如何验证及更改XenDesktop版本
查看>>
linux tc 对本机网卡限速
查看>>
WCF简单教程(8) 安全 - Windows认证
查看>>
单引号转义时load_file/outfile 生成一句话
查看>>
js的正则处理
查看>>
两日公开课:伯克利深度强化学习训练营 | 视频+PPT
查看>>
通过DockerFile创建ssh服务镜像
查看>>
windows server 2008中关于网络的进阶设定
查看>>
Python 并发编程(一)之线程
查看>>
苹果 vs AMD 高低互现
查看>>
手把手教你用C#打包应用程序(安装程序)
查看>>
软件架构设计模式简述
查看>>
模块化安装与删除openstack的dev(control、compute)与folsom(control)版本
查看>>
ISA系列之ISA Server 2004 中的新增功能--利用多个网络
查看>>
设计Unix下木马程序
查看>>