同步 – 依赖负载在CPU中重新排序
我一直在阅读
Memory Barriers: A Hardware View For Software Hackers,这是Paul E. McKenney的一篇非常受欢迎的文章.
本文强调的一点是,非常微弱的处理器,如Alpha,可以重新排序依赖负载,这似乎是分区缓存的副作用 论文摘录: 1 struct el *insert(long key,long data) 2 { 3 struct el *p; 4 p = kmalloc(sizeof(*p),GPF_ATOMIC); 5 spin_lock(&mutex); 6 p->next = head.next; 7 p->key = key; 8 p->data = data; 9 smp_wmb(); 10 head.next = p; 11 spin_unlock(&mutex); 12 } 13 14 struct el *search(long key) 15 { 16 struct el *p; 17 p = head.next; 18 while (p != &head) { 19 /* BUG ON ALPHA!!! */ 20 if (p->key == key) { 21 return (p); 22 } 23 p = p->next; 24 }; 25 return (NULL); 26 } > CPU0和CPU1有2个处理器. 题: >加载后重新加载负载 这让我想知道需要什么硬件支持才能防止依赖负载重新排序. 一个可能的答案是所有其他架构(IA64)没有分区缓存,因此不会遇到此问题,也不需要显式硬件支持. 任何见解?
简短回答:
在无序处理器中,加载 – 存储队列用于跟踪和实施内存排序约束.诸如Alpha 21264之类的处理器具有防止依赖负载重新排序的必要硬件,但强制执行此依赖性可能会增加处理器间通信的开销. 答案很长: 依赖追踪的背景 这可能是使用示例最好地解释的.想象一下,您有以下指令序列(为简单起见使用伪代码指令): ST R1,A // store value in register R1 to memory at address A LD B,R2 // load value from memory at address B to register R2 ADD R2,1,R2 // add immediate value 1 to R2 and save result in R2 在此示例中,LD和ADD指令之间存在依赖关系. ADD读取R2的值,因此在LD使该值可用之前它不能执行.这种依赖关系是通过寄存器进行的,它是处理器的问题逻辑可以跟踪的. 但是,如果地址A和B相同,则ST和LD之间也可能存在依赖关系.但是与LD和ADD之间的依赖性不同,在发出指令(开始执行)时,ST和LD之间可能的依赖性是未知的. 处理器不是在发布时尝试检测内存依赖性,而是使用称为加载 – 存储队列的结构来跟踪它们.此结构的作用是跟踪已发布但尚未停用的指令的挂起加载和存储的地址.如果存在内存订购违规,则可以检测到这种情况,并且可以从发生违规的位置重新开始执行. 因此,回到伪代码示例,您可以想象在ST之前执行LD的情况(可能由于某种原因,R1中所需的值尚未准备好).但是当ST执行时,它看到地址A和B是相同的.所以LD应该真正读取ST产生的值,而不是缓存中已经存在的陈旧值.因此,LD将需要重新执行,以及LD之后的任何指令.可以通过各种优化来减少一些开销,但基本思想仍然存在. 正如我之前提到的,检测这种依赖性的逻辑存在于允许推测执行存储器指令(包括Alpha处理器)的所有无序处理器中. 内存排序规则 但是,内存排序规则不仅限制处理器从其自己的内存操作中看到结果的顺序.相反,内存排序规则限制了操作的相对顺序,在一个处理器上执行的内存操作变得对其他处理器可见. Alpha例子 在依赖负载重新排序的情况下,处理器必须跟踪此信息以供其自己使用,但Alpha ISA不要求它确保其他处理器看到此排序.如何发生这种情况的一个例子如下(我引用了this link) Initially: p = & x,x = 1,y = 0 Thread 1 Thread 2 -------------------------------- y = 1 | memoryBarrier | i = *p p = & y | -------------------------------- Can result in: i = 0
概要 强制执行相关负载排序所需的基本硬件已经存在于所有无序处理器中.但是确保所有处理器都能看到这种内存排序会增加处理缓存行无效的附加限制.并且它可能在其他场景中添加额外的约束.然而,在实践中,似乎弱的Alpha存储器模型对于硬件设计者的潜在优势不值得花费软件复杂性并且增加了需要更多存储器障碍的开销. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby – Grunt / Bundler不会使用指定的sass版本
- “char * _EXFUN(index,(const char *,int));”的含义
- ruby-on-rails – 用于rails控制台/服务器等的Shell功能/别
- linearLayout等布局添加动态背景(运用xml)注意加上clicka
- c – Boost :: asio,共享内存和进程间通信
- Xcode 7 beta 4构建错误 – com.apple.CoreSimulator.SimRu
- Dojo中点击button弹出一个dialog
- ruby-on-rails – 用于RSpec的未定义方法instance_double :
- sqlite嵌入式数据库在linux下的编译
- NOSQL浅见总结