内存体系中的Consistent和Coherent(转)

在看体系结构相关的SPEC中,描述memory的术语中,比较常见的就是Consistent和Coherent了。这两个概念在现代体系结构中非常重要,但又容易混淆,因此在这里尝试说明一下。

首先,需要了解一下Consistent,一般翻译叫做连续性,不过这个翻译如果不了解的话约等于没有,所以还是使用Consistent了。什么时候会出现Consistent呢?如果一块内存区域可以被多个Master读写的时候,就会出现Consistent问题。Master可以是CPU的每一个PE,也可以是GPU,或者DMA。

那么Consistent描述的是什么行为呢?如果这块内存区域是Read-Only,或者所有访问这块内存区域的Master只发出读请求,那么就没有Consistent的问题。这个时候,所有的Master都能看到了同样的数据。

只读显然是多种情况中的一种,更常见的情况,是可以访问这块内存区域的Master中,有一个或者多个会写入这块内存区域。现在让我们丢掉Cache的问题,认为所有的Master对内存区域的读写都不会被Cache住。现在考虑一个问题,如果在一个3D绘图中,CPU准备数据写入到内存中,GPU从给定的内存中读出数据,这中间会有什么问题?很显然,CPU和GPU作为两个独立的Master,如果没有一种机制能够让CPU通知GPU数据什么时候准备好的话,整个GPU就不可能正常工作。这是Consistent的一个表现。当然,只要有点儿基础的人都知道这种情况该怎么办。

也就是说Consistent指的是如何保证数据的原子性不被破坏。

那么,现在让我们把目光从系统转到CPU内部。多核是现在处理器发展的方向之一,单核的美好时光已经一去不复返了。在多核处理器上,一个进程的多个线程可能并发地运行在多个物理PE上,这个时候,对于共享的内存区域就必须考虑到Consistent的问题。简单来说,就是多个需要保证读写在不同master之间的顺序性。如何保证呢,load-acquire/store-release,或者加锁,或者做memory barrier。

对于Consistent而言,硬件只提供解决Consistent的机制,而软件需要自行使用这些机制来保证Consistent

接下来就是Coherent了。当一份数据可以有多份拷贝的时候,就会出现Coherent问题。Coherent出现的最典型情况就是Cache的引入

对于单个Master的情况,即使引入了Cache,数据可以同时存在于主内存和Cache中,Master也总是可以使用Flush或者Invalidate的方式,来更新主内存中的数据。实际上,这种时候大多数情况下并不需要操作Cache的。

然而,如果引入了多个Master,并且每个Master都有自己的Cache的话,事情就变得复杂了。Master A写入主内存M位置L的数据D可能被Cache到A的cache中,这样B如果直接从主内存中读数据,很可能读到旧的数据D'

那么,怎么保证B能够拿到最新的数据呢?很直观的做法,禁掉Cache不就行了,然而这会带来性能方面的损失。还有一种做法,每个Master更新Cache的数据后,都需要保持主内存和Cache中数据是一致的,可以使用Write-through策略,或者每次更新之后都需要Flush一下。相比于禁掉Cache,这样性能会稍微好一点,然而,每次的写都会占用内存带宽,仍然不是一个良好的解决方法。

也就是说Coherent指的是如何保证数据始终是最新的而不被破坏。

硬件中,我们可以将Master的Cache彼此联合起来,这样Cache彼此维护数据的一致性,而只有在需要的时候才将数据写回到主内存中。这样,在提高硬件设计复杂度的前提下,可以实现性能的优化。例如,ARMv8体系结构中的shareable属性,就是硬件保证Coherent的一种表现。

总结一下,Consistent是由于多个Master对同一块内存区域的读写顺序造成的问题,只能由硬件提供相关的机制,由软件来保证。而Coherent则是由于同一块内存区域可能有多份拷贝(主要是Cache)而造成的数据的不一致性,可以由硬件来保证

 

参考链接:https://zhuanlan.zhihu.com/p/21387258?from_voters_page=true&utm_id=0

posted @ 2023-12-29 18:31  青山牧云人  阅读(268)  评论(0)    收藏  举报