作者注:
限于能力和时间,文中定有不少错误,欢迎指出,邮箱[email protected], 期待讨论。由于绝大部分是原创,即使拷贝也指明了出处(如有遗漏请指出),所以转载请表明出处http://www.cnblogs.com/e-shannon/
http://www.cnblogs.com/e-shannon/p/7495618.html
2 CAPI overview
2.1 背景
2.1.1 行业背景
2013年8月由IBM、Google 、NVIDIA等公司联合成立成立了OpenPower 基金会, 其目的是通过建立开源Power生态系统,在warehouse data center(仓储式数据中心)、HPC(高性能计算)等服务器领域与intel展开竞争[dream1] 。4年里,先后有150多家企业加入,涉及从芯片到I/O、固件、系统、软件等各个产业链。OpenPower成立后IBM于2014年推出的第一款CPU是Power8,而CAPI1.0(一致性加速处理器接口)是Power8 系统所支持的重要特性之一,用于减轻CPU负担,实现CPU加速的功能。
2017年IBM推出Power9,Power9 基于14nm FineFET工艺,8billion个晶体管(注:Power9将是检验IBM的openPower策略的重要筹码,希望能抢回HPC和超大规模数据中心市场份额的10%-20%)。同时作为Power9所支持的重要特性CAPI2.0已经公布,相比于1.0,支持PCIE Gen4(到底是4GB/s还是2GB/s的速率?Power9似乎指的是4GB/s),以及在AFU接口添加了DMA通道,支持PCIE的native 操作,便于AFU直接通过PCIE访问。值的一提的是其提供了NVlink接口可以直接对接nVIDIA的GPU,也可以复用为OpenCAPI的phy(bluelink)。(yxr注:OpenCAPI在后续会介绍)
2.1.2 技术背景以及开放式总线接口
由于在大数据/云计算/HPC(超算)/人工智能(深度学习)等大计算大存储领域,单靠CPU性能提升无法胜任越来越复杂的高运算量的需求。最近的趋势显示[dream2] ,CPU创造的价值越来越小,而加速器以及更多的依附于CPU的疯狂创新则创造了更大的价值,所以高速、低延迟、协同操作(coherent)的(CPU)高性能总线(或称为互联加速接口)成为了业界急迫的需求。CAPI则是在这种背景下出现(yxr注:对应于intel,则是QPI通道),但其依附于OpenPower的CPU体系。业界为了满足业务需求,更希望能出现一套开放式总线,独立于不同的ISA和CPU体系,并且不仅仅为了对接accelerator,而且也面向未来高速的memory,网络存储以及高速network,实现计算机集群的互联和高速运算。所以2016年共出现了3个开放标准,分别是CCIX,Gen-Z,OpenCAPI[dream3] 。
三个标准的目的相似,侧重点有些差异,成员也互相交叉,甚至有成员在三个组里(比如AMD、IBM、Xilinx、Micron等,而Google和nVIDIA仅仅在OpenCAPI,当然intel不在这三个组里)。
CCIX物理介质基于PCIE,实现处理器和加速器全cache一致性。而Gen-Z则侧重于机框之间的互联一致性加速。OpenCAPI则获得了IBM的Power9支持。(yxr猜测:相信最后这三个标准将会统一,因为其共同的敌人应该是intel吧,也许intel加入后又不同了)
2.2 Cache
CAPI里的coherent是指cache coherency。而理解cache coherency,需要从cache的认识入手,对于cache熟悉的读者可以略过本节,以下均是自己不专业地从网上搜罗整理。
2.2.1 浅析Cache
由于CPU运算速度要比内存读写速度快很多,这样会使CPU花费更多时间等待数据到来或把数据写入内存。内存一般由高密度的动态内存DRAM组成,所以其访问速度相对慢于CPU速度(需要行地址和列地址,以及刷新操作,等待周期等,并且功耗大)。
现代计算机中一般在CPU和内存之间插入了一个SRAM,作为cache,用于解决CPU速度运行速度快和内存访问速度相对慢的矛盾。CPU不再能直接访问内存[dream4] ,而是访问cache,见下面示意图
SRAM的访问速度远快于DRAM,克服了CPU访问内存的瓶颈,其缺点是无法做成大容量。引入 Cache(SRAM)的理论基础是程序局部性原理,包括时间局部性和空间局部性。即最近被CPU访问的数据,短期内 CPU还要访问(时间);被 CPU 访问的数据附近的数据,CPU 短期内还要访问(空间)。因此如果将刚刚访问过的数据缓存在 Cache中,那下次访问时,可以直接从Cache中取,其速度可以得到数量级的提高[dream5] 。
在高级的CPU中,存在二级缓存,服务器等CPU则达到三级缓存[dream6] 。Power9含有12个SMT8 core,每个core有三级缓存[dream7] ,10 MB Capacity L3+ 512k L2(SRAM),而一级缓存则由32kB instruction cache(I-cache)和32kB data cache(D-cache)组成。三级缓存工12x10MB=120 MB 其实是Shared Capacity NUCA Cache由eDRAM组成,目的是为了[dream8] 大容量并行计算以及异种互动。
如下是以intel core2 双核处理器为例,其为双核,使用二级缓存。1级缓存是每个core对应有32KB L1 数据和32KB L1 指令。而二级缓存为6MB[dream9] 为双核共享,其cache line均为64byte。(Yxr注:Power9与其相比,似乎是插入了一级SRAM作为2级缓存。)
http://www.cnblogs.com/xkfz007/archive/2012/10/08/2715163.html
2.2.2 Cache访问方式
如上图所示,CPU无法直接访问内存,只能沿着Register —> L1 Cache —> L2 Cache —> L3 Cache —> Memory —> Mass storage的层次结构进行访问。CPU访问内存则存在4种方式,
读写各两种,读有 look through 和 look aside方式,写有 write through 和write back
Look through:指的是CPU读请求只能发给cache,如果命中则cache回内容给CPU,结束本次访问。如果没有命中(hit),则cache将读请求发给内存。
Look aside: 则是CPU的读请求同时给cache和内存[dream10] ,如果cache命中,则cache回数据并且中断内存读。如果没有命中,则不中断内存读操作,继续内存访问,好处是减少了延迟,缺点是每次都将发起内存总线读操作,占用了内存访问总线[dream11] 。
Write through:透过本级缓存,直接把数据写到下一级缓存(或直接到内存)中,如果对应的段被缓存了,我们同时更新缓存中的内容(甚至直接丢弃)。优点是操作简单,保证缓存和内存一致,缺点是降低了系统写速度,占用了内存的访问总线。
Write back:(yxr注:有两种说法,回写时机不一样,不清楚哪种正确!!!)
1种说法.缓存不会立即把写操作传递到下一级,而是仅修改本级缓存中的数据,并且把对应的缓存段标记为“脏”段。脏段会触发回写,也就是把里面的内容写到对应的内存或下一级缓存中。回写后,脏段又变“干净”了。当一个脏段被丢弃的时候,总是先要进行一次回写[dream12] 。
2种说法. 数据一般只写到Cache,这样有可能出现Cache中的数据得到更新而主存(Main Storage)中的数据不变(数据陈旧)的情况。但此时可在Cache 中设一标志地址及数据陈旧的信息,只有当Cache中的数据被再次更改时,才将原更新的数据写入主存相应的单元中,然后再接受再次更新的数据。这样保证了 Cache和主存中的数据不致产生冲突。
有些(大多数是比较老的)CPU只使用直写模式,有些只使用回写模式,还有一些,一级缓存使用直写而二级缓存使用回写。这样做虽然在一级和二级缓存之间产生了不必要的数据流量,但二级缓存和更低级缓存或内存之间依然保留了回写的优势。
2.2.3 缓存映射方式和cache line
Cache的内部结构含有内存地址和cache内部地址映射关系,以及存储内存数据的单元。
Cache line是cache加载内存的基本操作单位,每次加载一个cache line而不是一个字节。大小是32(较早的ARM、90年代/2000年代早期的x86和PowerPC)、64(较新的ARM和x86)或128(较新的Power ISA机器)字节,(yxr注:cache line大小可能和DRAM内存的内部结构有关,一个基本内存访问的基本操作可能是8个时钟的数据,而数据线宽度为32,64,128bit (注意不要跨DRAM的bank[dream13] ))
每个cache line,都有如下类似的结构,tag是数据块在内存中的地址,data block则是数据内容,flag bits则是valid和脏等标志,甚至一些算法信息
而相对于内存的物理地址,则可理解为如下结构,其原因是缓存与内存的映射关系造成。
这里的 page 不是分页机制的page概念,而是cache 内部的page,line则是cache line所在的位置,offset则是具体数据所在字节(?理解正确吗),具体理解需要从cache的映射关系来看。
Cache与主存有三种映射关系,可参考如下资料(高速缓存与主存的三种映射方式[dream14]
http://blog.csdn.net/hs794502825/article/details/37937949 (ok)讲的比较好,这里直接搬过来), https://en.wikipedia.org/wiki/CPU_cache,http://blog.sina.com.cn/s/blog_5ccec1e30100yte3.html)
1、全相联映射方式 (full-associative)
2、直接相联映射方式 (direct map,相当于1-way associative) http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Memory/direct.html
3、组相联映射方式 (2-way,8-way N-Way Set-Associative) 这个是现在CPU中用的较多的方式,算是前面两种的组合折中[dream15]
http://blog.csdn.net/leoufung/article/details/48804627 http://blog.csdn.net/zdl1016/article/details/8882092
http://www.mouseos.com/arch/cache.html
1、全相联映射是指主存中任意一个块都可以映射到cache中任意一个块的方式,也就是说,当主存中的某一块需调入cache时,可根据当时cache的块占用或分配情况,选择一个块给主存块存储,所选的cache块可以是cache中的任意一个块。所以需要一个表存放cache和内存之间的关系,如下图
(Yxr注:这个就有点像CAM了,输入主存地址,输出index是cache的地址,然后找到对应的数据。在文中(1)Cache的组成结构_云中鸿雁_新浪博客提到,组相联映射方式中,在同一个Set中,Real Address Tag阵列多使用CAM(Content Addressable Memory)存放,以利于并行查找PS(Parallel Search)方式的实现)
优点是cache利用率高,命中率高。缺点是存储相联关系的存储器(相联存储器)庞大,查找整个cache,比较电路复杂,速度慢,无法做大。
2、直接相联映射方式
直接相联映射方式是指主存的某块j只能映射到满足如下特定关系的cache块i中:
i=j mod 2^C
主存的第0、2^C、2^(C+1)、…块只能映射到cache的第0块,主存的第1、2^C+1、2^(C+1)+1、…块只能映射到cache的第1块,……,主存的第2^C-1、2^(C+1)-1、…2^M-1块只能映射到cache的第2^C-1块。即:对2^C求余后余数相同的主存块对应cache中同一个块。如下图所示:
优点:比较电路最简单,地址映射方式简单,数据访问时,只需检查区号是否相等即可,因而可以得到比较快的访问速度,硬件设备简单。
缺点:cache块冲突率较高,余数相同的主存块无法同时进入cache,从而降低了cache的利用率。
3、组相联映射方式
结合了上面两种方法,这样主存的某一块不会限制在cache的某一块中,而是限制在某一组中。
组相联映射方式下,将cache分成2^u组,每组包含2^v块。主存的块与cache的组之间采用直接相联映射,而与组内的各块则采用全相联映射。也就是说,主存的某块只能映射到cache的特定组中的任意一块。主存的某块j与cache的组k之间满足如下关系:k=j mod 2^u
设主存共有2^s×2^u块(即M=s+u),则它们的映射关系如下图所示:
Yxr注:这里的组应该就是way[dream16] ,文章适合更进一步理解cache(http://www.mouseos.com/arch/cache.html)。在理解cache中的8-way set或者AMD 的2-way set,就是8组或者2组。Power8的L2 也是512 KB 8 way per core。
优点:块的冲突概率比较低,块的利用率大幅度提高,块失效率明显降低。
缺点:实现难度和造价要比直接映射方式高。
延伸阅读
1)现代CPU中,更多采用组相联映射方法。在Cache的组成结构一文(Cache的组成结构_云中鸿雁_新浪博客)中,有着更进一步讲述这几种方法的演进和优劣,以及组的个数和效率之间关系。值得进一步阅读。
2)在《理解 Cache》([email protected])中则举例了AMD和intel的CPU,如下是AMD的2-way cache
cache 中的 other 部分还包括了 cache 的状态信息,LRU(least Recently Used)算法等,还包括一些预解码,分支预测等一些信息
2.3 Cache Coherency
以上介绍了单CPU核的单个Cache的内部组成,当多个CPU的多组cache在一起工作时,就牵涉到cache的一致性。CAPI里的Coherent指的是cache Coherency[dream17] ,即缓存一致性。多核CPU中,均有各自的cache,如何保证各个cache的内容一致性以及和内存的一致性,是一致性协议需要解决的问题。
这里推荐一篇介绍cache coherency的文章。《Cache coherency primer》《缓存一致性入门》
http://www.infoq.com/cn/articles/cache-coherency-primer
文中介绍cache的来源、cache line(yxr注:有意思的是作者认为cache line应该是指一段内存内容,并不一定在cache中)的含义和cache访问所遵循的定理。指出一致性问题来源是由于多组cache造成的,而不是多核造成,如果多核共用一个cache,则不存在此问题。在解决一致性问题中提到了最普遍的方法,snoop协议,其物理基础是在多核系统里,每个CPU都有自己的cache系统,但同时和唯一的一个memroy控制器交互,所以均能够窥探(snoop)到memory 的访问,知道其他cache访问内存的动作,从而更新和操作自己的cache。在write-through模式中,各组cache知道其他cache的动作,可以马上更新,但是对于write-back模式,就存在问题,可能出现多个CPU核的cache同时更新一块内存。所以在修改本地缓存之前,就要告知其他处理器。处理回写模式这个问题的最简单方案,我们通常叫做MESI协议(梅西我最喜欢的球员啊,MESI是Modified、Exclusive、Shared、Invalid的首字母缩写,代表四种缓存状态[dream18] ).
原生的MESI协议
MESI是四种缓存段状态的首字母缩写,任何多核系统中的缓存段cache line都处于这四种状态之一,各个cache之间需要相互通信,完成各个状态的装换,保证cache的一致性。出于合理性,文中以相反的顺序逐个讲解MESI:
失效(Invalid)缓存段,要么已经不在缓存中,要么它的内容已经过时。为了达到缓存的目的,这种状态的段将会被忽略。一旦缓存段被标记为失效,那效果就等同于它从来没被加载到缓存中。
共享(Shared)缓存段,它是和主内存内容保持一致的一份拷贝,在这种状态下的缓存段只能被读取,不能被写入。多组缓存可以同时拥有针对同一内存地址的共享缓存段,这就是名称的由来。
独占(Exclusive)缓存段,和S状态一样,也是和主内存内容保持一致的一份拷贝。区别在于,如果一个处理器持有了某个E状态的缓存段,那其他处理器就不能同时持有它,所以叫“独占”。这意味着,如果其他处理器原本也持有同一缓存段,那么它会马上变成“失效”状态。
已修改(Modified)缓存段,属于脏段,它们已经被所属的处理器修改了。如果一个段处于已修改状态,那么它在其他处理器缓存中的拷贝马上会变成失效状态,这个规律和E状态一样。此外,已修改缓存段如果被丢弃或标记为失效,那么先要把它的内容回写到内存中——这和回写模式下常规的脏段处理方式一样。
MESI协议是一个合适的状态机,既能处理来自本地处理器的请求,也能把信息广播到总线上[dream19] 。E状态解决了“在我们开始修改某块内存之前,我们需要告诉其他处理器”这一问题:只有当缓存段处于E或M状态时,处理器才能去写它,也就是说只有这两种状态下,处理器是独占这个缓存段的。当处理器想写某个缓存段时,如果它没有独占权,它必须先发送一条“我要独占权”的请求给总线,这会通知其他处理器,把它们拥有的同一缓存段的拷贝失效(如果它们有的话)。只有在获得独占权后,处理器才能开始修改数据——并且此时,这个处理器知道,这个缓存段只有一份拷贝,在我自己的缓存里,所以不会有任何冲突。
反之,如果有其他处理器想读取这个缓存段(我们马上能知道,因为我们一直在窥探总线),独占或已修改的缓存段必须先回到“共享”状态。如果是已修改的缓存段,那么还要先把内容回写到内存中。
MESI定律:在所有的脏缓存段(M状态)被回写后,任意缓存级别的所有缓存段中的内容,和它们对应的内存中的内容一致。此外,在任意时刻,当某个位置的内存被一个处理器加载入独占缓存段时(E状态),那它就不会再出现在其他任何处理器的缓存中。
除了基于窥探(snoop)协议来完成cache coherency,文中同时指出还有一种基于目录的cache coherency协议,虽然延迟大,但更适用于大规模的多核系统,在《cache的理解》一文中,可以看到在 Intel 中,使用 Directory 结构来匹配查找数据
上面这个图显示了使用 Direcotry 结构进行查找,同样是需要匹配 page 值。这些 status 值和 AMD的other 异曲同工的作用,记录着每条 cache line 的状态值。
2.4 Power CPU的cache coherency系统
在Power多[dream20] CPU的体系下,多核cache的关系如下图所示
摘自http://www.csdn.net/article/2015-06-17/2824990
ccA就是cache coherency agent,猜测就是cache 一致性处理机构,完成了cache 一致性协议比如snooping(图中的probe应为此功能),MESI协议,或基于directory的更新。MC是memory controller,控制RAM的访问。而CAPI 则是基于PCIE的物理介质,通过CPU上的RC(PCIE root complex)访问MC。为达到cache一致性,在CAPI接口上应该有个类似ccA的模块,这里就是CAPP和PSL的一部分(见下图),其中PSL含有cache约256KB(为L2cache的一半)。
[dream1](服务器市场现在几乎是intel的天下?是这样吗,据说IBM的小型机性能远超intel x86,且高端市场主要用IBM小型机,其稳定性和性能扩展性远超intel。但是由于采用计算机群技术,通过分布式计算解决了稳定性和性能提升,所以基于intel的处理器的服务器反而处于优势地位。而IBM小型机非常贵,包括CPU也很贵,所以现在IBM推出OpenPower,估计也是针对这个问题,仿效arm,基于IP,降低CPU价格,其他厂家也能生产PowerCPU
[dream2]https://www.nextplatform.com/2016/10/17/opening-server-bus-coherent-acceleration/
What is going on here is that we are re-architecting the system,” Brad McCredie, the former president of the OpenPower Foundation and an IBM Fellow and vice president of development in IBM’s Power Systems division, tells The Next Platform. “No matter how you slice it, the processor is not improving cost/performance at the incredible rate and pace that it had in the past. And yet there is still this ever-growing demand for more and more compute capability, driven by these new workloads of artificial intelligence as well as simulation and analytics, there is this huge appetite to still produce more advanced systems. Less and less value is being driven by CPUs and more and more is being generated by accelerators, new memory technologies, and lots of crazy innovations that are attaching to processors. The value is shifting around, and in order to have the ability to mix and match technologies, we are going to need standards and Google, Hewlett Packard Enterprise, and Dell EMC see this very plainly.”
[dream3](213_CCIXGen-Z_BBenton.pdf,CCIX,Gen-Z,OpenCAPI_Overview&Comparison.pdf)
[dream4]但是也有的CPU可以旁路cache,直接访问内存,这个应该和CPU有关,引出了更多的信号同时给cache和内存
[dream5]具体多少,不清楚yxr..如下一段话虽然是硬盘,也能说明些问题。
硬盘的cache也有助于改进性能。虽然16MB的cache只能覆盖整个磁盘容量的0.002%,可别看cache只有这么一点大,其效果十分明显。它可以把一组零散的写入操作合成一个,也就是使磁盘能够控制写入操作的顺序,从而减少寻道的次数。同样的,为了提高效率,一系列读取操作也可以被重组,而且操作系统和驱动器固件(firmware)都会参与到这类优化中来。
[dream6]没有听说四级缓存
[dream7]三级缓存的作用明显吗?提高效能呢
[dream8]Big Caches for Massively Parallel Compute
and Heterogeneous Interaction
[dream9]是SRAM吗?
[dream10]1)有这种应用吗 2)物理上芯片实现上是否单独引CPU信号给内存?还是在cache中透传信号给了内存
[dream11]其实这个叫look through似乎更好,和write through一致嘛
[dream12]怎么有的网站werghryp,所遵循的一次回写。回写所遵循的规律有点不同
[dream13]我们已经知道,一个cache line对应的是主存中连续的几个字,那么这些字的低位对于映射一个cache line是没用的,比如说在一个32位系统中,一个cache line的大小是16个字,也就是64个字节,cache读取memory的数据时按照,cache line的尺寸读入,所以编程时组织数据结构,按照cache line的方式能够提升效率
[dream14]这里自己理解的并无信心,
[dream15]理解正确否?
[dream16]正确否?
[dream17]是这样吗?为啥在openCAPI中,还提到V3.30的openCAPI仅仅支持memory coherent,而不支持cache coherent(见CCIX,Gen-Z,penCAPI_Overview&Comparison.pdf 的page9)
[dream18] 为达到cache conherency,cache访问引入了MESI状态(梅西,四个字母代表四种状态),各个core之间需要相互通信,完成各个状态的装换,保证cache的一致性。
[dream19]这让我想起在TCP/IP offload中自己设计的的如何将TCP的访问无阻塞被各个模块使用,也是窥探也是采用总线通知收发模块以及Timer模块。蛮佩服自己的,^_^。可以多学习些控制协议!计算机专业的书记
[dream20]从(http://www.csdn.net/article/2015-06-17/2824990 介绍中似乎power系统采用directory方法,