Pages

Sunday, December 19, 2010

刘晓波获得诺贝尔和平奖之余

我写这篇文章的起因是我在推特上对刘晓波有几个批评,于是立马掉了不少 Follower。我不知道这两者是否有关联,但是这让我不得不认识到一个有趣的现象,也即在谈刘晓波其人其事的问题上,或许以前还有可以讨论的空间,但是自从他获得了今年的诺奖和平奖之后,似乎已然完全没有了回旋的余地。不管出于何种原因,或者是不读历史不知刘当初如何上中央电视台作证天安门屠杀没有死一个人,或者是不问时事不知刘晓波如何对高智晟这样的维权律师落井下石,对杨佳污蔑,总之众人都是一片掌声。当然也有不少明白真相或者似乎明白真相的群众。比如有人说刘晓波是把天安门清场理解成仅仅是纪念碑一带的活动,刘晓波是真的没有看到在外围的屠杀。但是据吴仁华老师的《天安门血腥清场内幕》一书记载,即便是纪念碑一带,也是有人死亡的。即便刘晓波再没有看见,在当时如此恐怖如此疯狂的情形下,他如何就能做出肯定断言,声称天安门没有死人?又有人在推特上和我说,“僅僅因為早期言論就否定一切,一個人的道德是從長期的行為來判斷的。”显然他是指刘晓波作伪证之后幡然悔悟对自己来了一番痛心疾首的悔悟,并且《零八宪章》足以抹去他历史上的斑点。但是我要说,我不仅仅是因为他的早期言论就否定他,我看的正是他长期的行为!我指的是什么?我指的正是他对高智晟等受到迫害的维权律师和杨佳这样原始正义捍卫者的落井下石。我说落井下石,是一个事实判断,未必是价值判断--虽然我越来越认为这也是一个价值判断。当然有人会辩解说这是晓波的非暴力抵抗的原则。那么我且抛开刘晓波式的所谓非暴力抵抗不谈,我们来看看刘晓波到底对高智晟和杨佳事件做出何种评论,他何以就忍心说出这样的话?对高智晟律师一案,刘晓波说,“如果高智晟案进入司法程序,我们敦促司法当局公开审理,确保司法公正和被告人得到充分的法律辩护。”这简直是荒唐。如果在刘晓波现如今身陷囹圄的局面下,我站出来说,“我认为刘晓波应当得到公开公正的审理,我敦促立刻将刘晓波案件纳入正常的司法程序,我相信党和政府一定会给刘晓波一个公正的评判”,不知道各位是和看法,做何反应?对杨佳,他说,“事实上,在互联网时代的中国,杨佳的个人维权也并非穷尽了所有非暴力手段,起码还有一条非暴力维权之路——通过在媒体上公开他的冤情和诉求 来寻求舆论救济。传统媒体不行,他还可以利用互联网,类似杨佳的情况大概还不至于被封杀。试想,如果杨佳把他的遭遇和维权过程持续地在网上披露,说不定会 引发关注而变成一个公共话题,那么杨佳本人肯定会得到网络民意的支持,鼓励他坚持依法维权,上海警方也将受到网络舆论压力,他也许就不会采取暴力复仇的极 端手段。”我要来替杨佳问你一句,以你如此的声望,几乎举全国有良知的公民之力,尚且是十一年牢狱之灾,你又何忍心说出让杨佳走什么媒体渠道网络渠道这样的鬼话出来?我们根本不用讨论什么非暴力抵抗,只要想想,在高杨二人一个生死不明一个身首异处的基本前提下,刘晓波怎能说出这种为虎作伥助纣为虐的话来?于情于理能说得通吗?

当然一片莺歌燕舞之中,仍然能够听到一些不同的声音。方励之教授的奥斯陆日记里面回忆了当初晓波先生是如何使用言论自由权来对自己“开骂”的。魏京生先生的文章《如今的诺贝尔和平奖给人们提供了什么》对刘晓波获奖颇有微词。安魂曲徐水良两人也各自有文章对刘晓波的人品道德提出了质疑。不过无论方励之还是魏京生,他们或暗有讥讽,或明确表示对刘晓波其人其事的鄙视,都毫无疑问地表明了对于刘获奖的明确支持。这正是他们和刘晓波的本质不同之处。要行使言论自由,基本前提是言论双方都是自由人。如今刘晓波身陷囹圄,不具备对等谈话的条件,那么首要之举,乃是抗议中共的暴举,营救刘晓波出狱。然后再来和他聊一聊过往,算一算账簿。但是这并不代表可以把刘晓波的过去一笔抹干净,也不代表可以把他对高杨等人的评论抹干净。到那个时候,我们或许还可以讨论一下到底非暴力抵抗是什么,刘晓波式的非暴力抵抗又是什么。但是现在能做的,是记住刘晓波其人其事,然后为诺贝尔奖委员会高唱赞歌。

向量处理器(2)

2. 向量处理器基本体系结构

一个向量处理器通常由一个普通的流水化的标量单元加上一个向量单元组成。在这个向量单元里的所有功能部件都有几个时钟周期的延迟。这使得能够使用较短的时钟周期,并且与复杂的需要深度流水化来避免数据 hazard 的向量运算兼容。大多数的向量处理器所允许的向量运算包括浮点运算,整型运算或者逻辑运算。这里我们重点关注浮点运算。标量单元基本上和我们在第二章和第三章里面讨论过的高级的流水线化的 CPU 里面的没区别。并且实际上商用的向量处理器里面都同时包含了乱序的标量单元(NEC SX/5)和 VLIW 的标量单元 Fujitsu VPP5000)。

向量处理器主要有两种类型:向量-寄存器(vector-register)处理器和内存-内存(memory-memory)处理器。在 vector-register 类的处理器中,所有的向量操作--除了 load store--都是在向量寄存器(vector register)里面进行的。这类的处理器就和我们在标量处理器里面谈过的 load-store 体系结构相对应。在 80 年代后期发布的几乎所有向量计算机都采用了这个结构,这其中包括 Cray Research 的处理器 Cray-1Cray-2X-MPYMPC90T90SV1 X1),日本的超级计算机(从NEC SX/2 SX/8Fujitsu VP200 VPP5000,以及Hitachi S820 S-8300)以及迷你超级计算机(从 Convex C-1 C-4)。在 memory-memory 类的向量处理器中,所有的向量运算都是从内存到内存的。第一个向量处理器就是这种类型,CDC 系列的亦是如此。从现在开始让我们把注意力放在 vector-register 类的处理器上我们会。在这个附录的最后(第10小节),我们会简单地讨论一下为什么 memory-memory 类的处理器没有 vector-register 类的处理器那么成功。

我们讨论的 vector-register 类的处理器主要由图 F.1 中的部件组成。这个基本上类似 Cray-1 的处理器是我们整章的讨论基础。我们把它叫 VMIPS--它的标量单元就是 MIPS,而向量单元则是 MIPS 的扩展。本小节余下部分将讨论 VMIPS 和其他处理器有何相关。


 F.1 VMIPS 的基本结构。这个处理器有一个类似 MIPS 的标量单元。另外还有 8 个包含 64 个元素的向量寄存器,并且所有的功能部件都是向量运算单元。定义了包括算术运算和访存在内的特别的向量指令。在这张图里面我们包括了逻辑运算和整型运算的部件,这些部件在标准的向量处理器里面其实也是存在的。但是除了后面的练习题之外我们不会讨论这两个部件。标量寄存器及和向量寄存器都有大量的读写端口以支持同时多个向量操作。这些端口通过一组 crossbar (图中灰色所示)和向量功能部件的输入输出相连。在第四小节中,我们会再加上 chaining 的部分,它需要更强的互联能力。

VMIPS的主要组成部分是:
  • 向量寄存器(Vector registers):每个向量寄存器都是一个定长的 bank,能够容纳一个向量。VMIPS 8 个向量寄存器,每个寄存器能够容纳 64 个向量元素。每个寄存器至少有两个读端口和一个写端口。这能够保证需要不同向量寄存器的多个向量运算能够互相同步进行[1](我们并不考虑由于寄存器端口短缺而引起的问题。在实际的机器中,这会导致 structural hazard)。总共 16 个读端口和 8 个写端口通过一对 crossbar 和功能部件的输入输出相连(我们在这里简化了对于 vector-register 类的处理器的寄存器文件的描述。真实的机器里会利用在一条向量指令里规则的访问模式来简化寄存器文件的电路设计[Asanovic 1998]。比如 Cray-1 就能够设计使得每个寄存器只需要一个端口)。
  • 向量功能部件(Vector functional units):每个部件都是完全流水化的,并且每一个新的时钟周期可以开始对于一个新向量元素的操作。另外还需要一个控制部件来检测 hazard,包括功能部件的冲突(structural hazards)和寄存器访问的冲突(data hazards[2]。如图 F.1 所示,VMIPS 有五个功能部件。为了简化讨论,我们将只讨论浮点运算单元。取决于不同的设计,标量运算可能使用向量功能部件,或者有单独的一组功能部件。我们这里假设功能部件是共享的,并且,再一次忽略任何可能的冲突。
  • 向量访存单元(Vector load-store unit):这是一个能够 load store 一个向量到主存的单元。VMIPS 中的 load store 操作是完全流水化的,因此在一开始的延迟之后,寄存器和内存之间的带宽可以达到每一个时钟周期一个 word。这个单元通常也处理标量访存工作。
  • 一组标量寄存器(scalar registers):标量寄存器能为标量功能部件提供输入数据[3],并且也能为内存访问单元提供地址。这些其实就是MIPS中常见的 32 个通用寄存器和 32 个浮点寄存器。标量数据从标量寄存器中读出,然后锁存到向量单元的一个输入之中。
F.2 展示了一些典型的向量处理器的特征,包括寄存器的大小和个数,功能单元的数目和类型,访存单元的数目。最后一栏展示的是一个机器中 lane 的数目,也即可以同时执行一个向量中各个元素操作的并行流水线的数目。第四小节会详细描述 Lane 的概念。这里我们假设 VMIPS 中每个功能部件只有一个流水线(也即一个 lane)。


F.2 几个 vector-register 类型的体系结构的特征。如果某个机器是多处理器(multiprocessor),上面只列出一个处理器的数据。有几个机器采用了不同频率的标量和向量单元,上面的频率数据是向量单元的。Fujitsu的机器的向量寄存器是可配置的:8K 64-bit entry [4]是可以变化的(比如在 VP200 里面,可以从 8 个寄存器,每个包含 1K 和元素到 256 个寄存器,每个包含 32 个元素)。NEC 的机器有 8 个前段的向量寄存器和算术运算单元相连,还有 32-64 个后端寄存器连接内存和前段寄存器。Add 流水线进行加法和减法操作。Hitachi S810/820 里面的 multiply/divide-add 单元先进行一个浮点的乘法或者除法运算紧跟着一个加法或者减法操作(multiply-add 单元先进行一个浮点的乘法运算紧跟着一个加法或者减法操作)。注意大多数的处理器使用向量浮点单元来进行向量整型运算,还有一些处理器使用相同的功能单元来进行向量和标量操作。每个 vector load-store 单元能够执行一个独立的,可以相互重叠的 load 或者 store 操作。Lane 的数目,就像第四小节中提到的,是每个功能部件中并行流水线的数目。比如,NEC SX/5 的乘法部件可以在一个时钟周期之中完成 16 个乘法运算[5]。有些机器可以把一个 64-bit lane 分离成 2 32-bit lane以提高那些对精度要求不高的程序的性能。Cray SV1 Cray X1 可以把有 2 lane 4 CPU 组合成好像一个有 8 lane CPUCray把它叫做 Multi-Streaming Processor MSP)。

VMIPS 中,向量指令采用和 MIPS 指令相同的名字,只是多了加了“V”。这样的话,ADDV.D 就是一个把两个双精度的向量相加的操作。向量指令的输入或者是一对向量寄存器(ADDV.D)或者是一个向量寄存器和一个标量及存取(ADDVS.D)。后者的标量输入被所有的向量元素视为输入--ADDVS.D 会把标量寄存器的内容加到向量寄存器的每一个元素上。标量值在指令发射时被拷贝多份到功能部件。大多数的向量操作都有一个向量目标寄存器(vector destination register),也有一些操作的结果是被存储到标量寄存器里的。LV SV 代表向量 load 和向量 store操作。他们 load 或者 store 一整个双精度的向量。一个操作数是一个要被 load 或者 store 的向量寄存器里,另一个是一个 MIPS 的通用寄存器,保存该向量在内存中的起始地址。图 F.3 列出了 VMIPS 的向量指令。除了向量寄存器之外,我们还需要两个特殊用途的寄存器:向量长度寄存器(vector-length register)和向量掩码寄存器(vector-mask register)。我们分别在第三和第四小节会谈到这两个寄存器和他们的用途。


F.3 VMIPS 的向量指令。这里只列出了双精度的指令。除了向量寄存器之外,还有两个特殊寄存器,VLR(在第三节谈到)和 VM(在第四节谈到)。假定这些特殊寄存器都在 MIPS coprocessor 1 中,也即和 FPU 寄存器在同一空间中。有 stride 的操作会在第三小节提到。新建索引和索引化的访存操作会在第四节里提到。

---------------大家好,我是分割线---------------

[1] 在后面我们会看到 convoy 这个概念。一个 convoy 表示一组可以同时执行的向量指令。他们可能访问不同的寄存器,我们必须提供足够多的端口以保证不会发生端口短缺。
[2] 这里的寄存器访问的冲突不是指端口短缺引起的冲突。而是由于对于数据依赖不正当的处理而引起的对寄存器错误访问。
[3] 想一下什么情况下向量运算需要标量数据?什么情况下向量运算的结果需要写到标量寄存器里面?
[4] 这里的 entry 指的是一个向量寄存器里面的一个元素。64-bit 是指每个元素是 64-bit 长。
[5] 更精确地说,是完成16个来自不同向量的操作。

Saturday, December 18, 2010

Terminology

这是物理上独立的一个页面,但是在逻辑上他依附于从这篇文章开始的一系列文章。它的主要目的是澄清在我的翻译过程中令人望而生畏的体系结构中莫衷一是的术语。
1. dependency/hazard:这两个说法严格来讲是可以区分的,但是大多数情况下大家会混用。严格地说,dependency 是一个程序本身的特性,而 hazard 是由于对于 dependency 的不正当处理造成的处理器的混乱。 
2. in flightIn flight 的指令并非一定仅限于正在 FU 里面执行的指令。更广义地讲,他也包括已经执行完毕但是没有 retire 的指令和正在 reservation station 中等待的指令。从这个意义上讲,instruction window 包含的就是所有 in flight 的指令。 
3. instruction window 有两个截然不同的说法。比较常见的解释是,instruction window 中的指令是那些正在 functional unit 中执行的指令。或者也可以扩大一下,是在ROB中还没有 retire 的指令。在这个说法中,instruction window 其实只是一个逻辑上的概念。整本量化里面应该使用的是这个含义。另一种说法是指的在 instruction fetch decode/renaming 之间的一个 buffer。当由于某种原因不能进行 decode 或者 rename 的时候,fetch 单元会把指令取到这个 buffer 里面而不停顿。不过通常这个 buffer 被称为 instruction queue。这个说法中,instruction window 是一个物理上存在的存储结构。 
4. interlock/stall/bubbleinterlock stall 可以认为是一件事情,即使得流水线停顿。通常停顿流水线的方法是 clock gating,或者说关闭流水线寄存器的 load enable 信号。但是组合电路的特性是即使不往寄存器里写,每个周期仍然会有数据被读出,这些数据是无效的因为前半段的流水线正处于停顿状态。这时候我们需要一个 valid 位来告诉后半段的流水线级:现在给出的数据是无效的,不要处理它,直到 valid 位置 1。把 valid 0 的操作通常被称为插入了一个 bubble
5. memory pipeline:概念上讲 memory pipeline 是指可以独立进行访存请求的通路。通常来讲,一个 memory system 有一条 memory pipeline,因为我们只有一条 address bus 和一条 data bus。因为在同一个时刻我们只能进行一个访存请求(虽然我们可以同时有多个 bank 在工作)。如果我们增加一组 bus,那么就可以说我们增加了一条 memory pipeline。有两种办法增加 memory pipeline。一种是现在所谓的多通道技术(multi-channel)。也即有两个独立的内存控制器(memory controller)。分别控制两套物理上独立的存储系统。另一种办法就是在向量处理器里面采用的,仍然只有一套物理上独立的存储系统,但是每个 memory bank 现在有多个端口,每个端口匹配一组 address data bus。如果现在每个 bank 有两个端口,那么我们需要两组 address/data bus。这样我们可以同时发出两条访存请求,访问两个不同的 bank,并且可以在一个周期接受两个数据。在 Corinna Grace Lee Ph.D. thesis 中提到说,相比于 superscalar 处理器而言,向量处理器需要的连接 CPU memory system 的管脚数目明显要少,因为即使有多个 memory port,但是仍然可以只需要一组 bus,而不是想超标量处理器里那样每个端口都需要匹配一组 bus。她的意思应该是,对于向量处理器而言,访存地址的计算是在 memory system 中完成的,CPU 只需要一次性提供一组基本的访存模式的信息即可,因此虽然 memory controller 的设计是复杂的,但是一次 address bus 的使用就可以触发多个(同时的)访存请求。而对于超标量处理器而言,每一次访存请求的地址都需要 CPU 端首先计算出然后传送到 memory system。因此如果需要同时进行多个访存的话,就需要多条 address busLee 也提到,在向量处理器中,gather/scatter 是一个特例,因为这类操作的地址没有固定模式,需要 CPU 端计算之后分别发送到内存系统。但是现在向量处理器完全有能力由内存系统完成这一计算过程。

    向量处理器(1)

    我决定翻译《计算机体系结构--量化研究方法》第四版附录F。原因在于向量处理器现在变得异常重要。可以说向量处理器是 GPU 的先驱。要从体系结构上理解 GPU,没有道理不先理解历史上的向量处理器。很多向量处理器里面用到的技术,在现在最先进的微处理器中又奇迹般地得到了重生。比如 Cray-1 里面的 T Register File B Register File,和 Stream Processor 中的 Stream Register File SRF)如出一辙。而现代面向通用计算的 GPU 中的Shared Memory S Register File 以及 A Register File的设计初衷也有异曲同工之妙。当然另一个原因是我没有看到有关量化附录的翻译。

    这个附录的作者是 Krste Asanović。他本人的Ph.D.  Thesis 就是一个向量处理器的设计。据说随着 David Patterson 慢慢地不管事,现在他已经成为了了 ParLab 的实际领袖。我完全是抱着学习这个附录的心态来翻译的,任何质疑都可以在下面留言。

    最后要说的一点,体系结构里最让人头疼的事莫过于五花八门的术语了,而如果要在中英文之间切换这些术语则更恶化这个现象。我的策略是两个。第一,如果有非常好非常成熟非常通用的中文翻译,我用中文--毕竟我是在翻译。但是即使这样我也会用括号表明英文术语。第二,有些术语本身有很大争议。比如 issue dispatchX86 MIPS 对他们的使用完全相反。我于是准备采用另一个页面,来解释那些令人困惑到发指的术语,以免读者完全理解错误原文应有之义。另外,原文之中有一些我认为讲得不是特别清楚或者难以理解的地方我都以注释的形式给出我自己的理解。

    ---------------大家好,我是分割线---------------

    我当然没有在发明向量处理器。现如今就我所知就已经有三种向量处理器存在了。他们是 IIIliac-IV (CDC)Star,和 T1(ASC)。这三者都是向量处理器的先驱作为先驱的一个问题是你总是要犯错误,而我绝对,绝对不想成为先驱。所以成为后来者的好处是你总是可以看到前人犯了什么错误。
    Seymour Cray


    1. 何出向量处理器?

    在第23章我们看到了如何通过每个时钟周期发射多条指令和利用更深的执行单元流水线来开发指令级并行(ILP)以显著提高性能。(这个附录假定你已经完整阅读了第23章和附录G。另外,对向量处理器的内存系统的讨论需要你阅读附录C和第5章。)不幸的是,我们看到在挖掘更大程度的 ILP 的时候遇到了各种各样的困难。

    随着我们增加指令发射的宽度和流水线的级数,我们同时也需要更多的不相关指令以保持流水线忙碌。这意味着可以同时 in flight 的指令数目的增长。对于一个动态调度的处理器而言,这意味着硬件资源比如指令窗口(instruction window),ROB,重命名寄存器 renaming register file)也要相应增长以保持足够的能力去维护所有 in flight 的指令的信息。更糟的是每一个硬件单元的端口都要随着发射宽度的增长而增长。跟踪所有  in flight 的指令之间依赖性(dependency)的逻辑随着指令的数目以 2 次方的关系增长。即使对于一个把更多的调度工作转移到了编译器上的静态调度的 VLIW 处理器而言,它仍然需要更多的寄存器,更多的寄存器端口,更多的 hazard interlock 逻辑(我们假定由硬件在指令发射的时候检测是否需要 interlock)来支持更多的 in flight 指令。这同样导致了电路规模和复杂度的 2 次方增长[1]。如此快速的电路复杂度的增长使得设计一个能够控制大量 in flight 指令的处理器困难重重,而且这反过来实际上也限制了发射宽度和流水线深度。

    向量处理器早在 ILP 处理器之前就已经成功商业化了。它采用了一种不同的策略来控制多个深度流水的功能部件。向量处理器提供了高层的对于向量--线性数组--的操作。一个典型的向量操作是两个 64 个浮点元素的向量相加得到一个新的 64 个元素的向量。这条向量指令等同于一整个循环,每一次迭代计算出一个元素的结果,更新循环变量,然后跳转回循环头部继续执行。

    向量处理器有以下几个重要的特性使得它能够解决大多数上面提到的问题: 
    • 一条向量指令能够做很多事情--它等价于一整个循环。每条指令代表了数十上百条的操作,所以为了保持多个深度流水化的功能单元忙碌而需要的 instruction fetch instruction decode 的带宽急剧减少了。 
    • 通过使用一条向量指令,编译器或者程序员显式地指出了在一个向量之中的各个元素之间的计算互相独立,所以硬件不需要检测一个向量内部的 data hazard。可以使用一组并行的功能单元或者一个非常深度流水的功能单元或者任何以上两种方式的组合来计算向量中的各个元素。
    • 硬件只需要检测两条向量指令之间的 data hazard,而不是每个向量之中的元素之间的 hazard。这意味着所需的依赖检测逻辑的规模其实和标量处理器所需的大致相同,但是现在更多的(对于向量元素)操作可以同时 in flight 
    • 向量指令的访存有固定可知的模式。如果一个向量的元素是相邻的,那么从一组高度 interleaved memory bank 中取那个向量会效果非常好。相对于访问 cache 而言更高的访问主存的延迟被均摊了,因为一个向量访存操作是为向量中的所有元素发起的,而不只是一个元素。 
    • 因为一整个循环都被一条向量指令代替了,而这条向量指令的行为是可预期的,所以通常由循环分支而引起的 control hazard 现在不存在了。
      因为这些原因,向量操作对于同样数目的数据进行操作的时候比相应的一系列标量指令要快得多,所以设计者们如果发现他们的应用程序会经常进行向量操作的话会在设计中包含有向量单元。

      向量处理器尤其对于大规模的科学工程计算特别有效,包括汽车碰撞模拟和天气预报。这些应用程序通常需要一台超级计算机跑上几打个小时来处理 Gigabyte 级别的数据。高速的标量处理器依赖于 cache 来减少访问主存的延迟,但是大规模长时间运行的科学计算程序通常有很大规模的工作集,并且通常局部性非常低,这导致 memory hierarchy 的性能非常糟糕。所以标量处理器会提供旁路 cache 的机制如果软件发现访存的局部性很差。但是使得主存饱和需要硬件跟踪数百上千条的 in flight 的标量访存操作,而这在标量处理器 ISA 中已被证实开销是非常大的。相反,向量 ISA 可以只使用一条向量指令就可以发起对于一整个向量中元素的访存操作,所以非常简单的逻辑就可以提供很高的带宽[2]。

      当这个附录上一次在 2001 年写的时候,诡异的向量超级计算机已经慢慢地从超级计算机领域中淡出了,取而代之的是超标量处理器。但是在 2002 年,日本造出了当时世界上最快的超级计算机,the Earth Simulator。它是为创造一个“虚拟星球”来分析和预测世界环境和气候变化而设计的。它比之前最快的超级计算机还要快 5 倍,并且比身后的 12 个超级计算机加起来还要快。这在高性能计算领域引起了一阵骚乱,特别是在美国。美国人被如此之快地就丢失如此具有战略意义的高性能计算阵地而感到震惊。The Earth Simulator 比那些与之竞争的机器有更少的处理器,但是每一个节点都是一个单芯片的向量微处理器。它对于很多具有重要意义的超级计算代码都有非常高的性能--原因就像之前提到的。The Earth Simulator 以及Cray 发布的新一代向量处理器的影响力导致了对于向量处理器的重新关注和重视。
        
      ---------------大家好,我是分割线---------------

      [1] 为什么是 2 次方请看原书第三章第二小节。简单来讲,这就是一个排列组合的问题。
      [2] 这段话的意思简单来讲就是通常高级的标量处理器里面的内存系统是非常复杂的,需要 MSHR 这样的结构以及很复杂的访存调度算法甚至编译器的优化来提高访存效率,充分利用内存接口本就不高的带宽。而对于向量机而言,由于访问模式规则,非常简单的内存系统的设计配搭上一条向量指令就足以使得内存带宽饱和。

      Tuesday, December 14, 2010

      SC10: Green500 and Booth "Awards"

      好吧我食言了,我还是准备再翻译一篇 Steve Keckler 关于 SC'10 blog,主题是关于绿色计算。在国内的 bbs 上,有人戏称之为和谐计算--一个非常应景的主题。可以看到 NVIDIA 把绿色计算作为噱头来吸引眼球是有来头的。在单线程性能糟糕的情况下,NVIDIA 抛出以下三条断言。第一,将来的应用大多数将是面向吞吐率的;第二,GPU 能够以牺牲单线程性能为代价获得极高的吞吐率;第三,为了获得相应的吞吐率表现,GPU 付出的能耗代价较之 CPU 不值一提。这三点从逻辑上环环相扣,几乎无懈可击。

      ---------------大家好,我是分割线---------------

      就像“更高,更快,更强” (Citius, Altius, Fortius) 的奥林匹克精神一样, SC10也有一系列关于高性能计算机的榜单,而不仅仅是最初的 Top500。绿色500  (The Green500) 是由 Virginia Tech Wu Feng 和其他一些人在 2007 年发起的。其目的在于增进对于高性能计算机系统中功耗效率的关注。这个榜单已经演化成为各大计算机供应商和超级计算中心标榜自己的工具。在介绍这个榜单的时候,Wu 表达了对于这个榜单可能被滥用和戏弄的忧虑。他提出了几点让此份榜单更有实际意义的建议,比如将测试程序扩展到 LINPACK 以外和制定更为严格的评测和报告功耗数据的标准。

      Wu 邀请了国家超级计算应用中心 (National Center for Supercomputing Applications, NCSA) Craig Steffen 做了一个关于他们是如何评测 Green500 要求的相关数据的方法论(他们称之为EcoG)的报告。Craig 搞了些很酷的照片,展示了他们是如何把一个夹子式的电流探测器嵌入到一个PDU (power distribution unit) 里面去的。其输出直接和一个采集一秒间隔瞬时功耗的数据采集器相连。不过别在家里尝试这玩意儿--那些 PDU 是工作在 208V 下的。被测试的 PDU 是总共工作的 128 个中的 8 个,这符合 Green500 的规定,也即允许通过汇报一个系统中子系统的数据并扩展到整个系统的方法来报告整个系统的数据。Craig 展示了一些在跑多遍 LINPACK 程序是功耗随着时间变化的图片,非常酷。即使是在一遍运行内,功耗也有 15%(峰值到峰值)的波动,并且平均功耗其实是随着运行的进行减少的。Craig 指出他们还想从 200 毫秒(他们电流采样器的最高分辨率)开始以更细的粒度来抓取数据。这样他们就可以把功耗变化和应用程序的行为更好的联系起来。另一个有趣的方面是 EcoG 决定汇报一遍 LINPACK 运行之后 80%  performance/Watt  数据(从 10% 开始)而不仅仅限于 Green500 规定的 20% 的下限。他们认为去掉启动和完结阶段的中间 80% 的数据相比选取最优的 20% 的数据更有代表性。我倒是很好奇其他那些机器上面功耗是怎么随着时间推移变化的。

      在吊足大家胃口之后,Wu 终于发布了 Green500 Top10 的排名。其中 8 个都是异构系统(或者基于 Cell,或者基于 GPU)。他还颁发了一下三个 Green500 奖项:
      • “世界最和谐超级计算机” (Greenest Supercomputer in the World) 奖颁给了位于 IBM 研究院的 IBM BlueGene/Q 原型系统。这个计算机以 1684 MFlops/Watt  (总共 38KW)的数据领衔榜单。我之后顺道去 IBM 的摊位上瞅了一眼他们的硬件系统。虽然没有我在前几天提到的 Blue Waters 那么有气场,但是 BlueGene/Q 还是用了一组定制技术包括一个由 BlueGene 芯片和最多 16GB 的本地存储组成的定制节点卡。这个系统也是水冷的,去除掉了一些诸如风扇电源之类的东西,并且很有可能通过运行在低温下降低了漏电功耗。
      • “世界最和谐超级计算机产品”(Greenest Production Supercomputer in the World) 奖颁给了 Tokyo Institute of Technology Tsubame 2.0。它以 958 MegaFlops/Watt  (总共1244 KW)的数据排名榜单第二。Tsubame 2.0 已经被实际部署了--它为每两个 Intel Westmere CPU 配备了 3 NVIDIA Tesla 20 系列的 GPU。这个 GPU/CPU 比例比榜单靠后的其他超级计算机都要来得高。
      • “世界最和谐自建计算机” (Greenest Self-Built Computer in the World) 奖颁给了 NCSA EcoG。它以 933 MegaFlops/Watt (总共36KW)的数据名列第三。EcoG是一个和 NVIDIA Research 合作的学生项目(我几天前提到了这个机器)。EcoG 采用了 1:1 GPU/CPU 芯片,但是使用了Core i3 代替更高端 CPU 芯片以期以牺牲串行性能的代价获得更好的 CPU 能耗效率。值得一提的是 EcoG 是由一些在网上就能买到的日常组件搭建而成的。

      ---------------大家好,我是分割线---------------

      最后 Steve 的一些闲聊的话就省略了。可以看到忝列 Top500 榜单第一的天河-1A Green500 Top10 中却没了踪影。这么一大坨废铜烂铁,不能跑实际应用,还是吃电怪兽,真是一朵奇葩啊。

      Monday, December 13, 2010

      SC10: Dally Keynote, Heterogeneous Computing Systems

      我将翻译一篇 Steve Keckler NVIDIA 写的文章。原文网址点。我计划在这个寒假译介一系列和体系结构相关的科普文章。除了传播的考虑之外,还有一点私心在于强迫自己认真得去读一些文章,蜻蜓点水实在是在犯罪。直到把这篇文章翻译完,我终于意识到这是一篇软文--但是不翻译的话,我又怎么会知道呢?

      ---------------大家好,我是分割线---------------

      把时间耗在 Supercomputing'10 这世界上最大的超级计算会议上,有点像喝消防栓里的水一样--除了能够听到无数技术报告之外,同时也是一个 会见同僚的绝佳机会。我大概一天只有 45 分钟的时间是没有排在日程里的!今天,我想向各位报告三件聚焦于异构高性能计算(heterogeneous high-performance computing) 的事件。

      今天早上的高光时刻乃是 Bill Dally 做的 Keynote 报告。他是 NVIDIA 的首席科学家 (Chief Scientist)和高级副总裁 (Senior Vice President)。当然他也是我的老板(并且在遥远的过去曾经是我 Ph.D. 的导师)--所以别指望我从我这里得到对于他的演讲的任何公开批 评!Bill 的演讲的题目是(坐稳了,光年外的粉丝们)"GPU Computing to Exascale and Beyond."  他首先聚焦于 GPU 的能源效率问题,展示了当今 Top500 系统的性能/耗能情况。比如,天河-1A 异构 GPU 计算机,Top500 的第一名得主,从性能/功耗 (flops/watt) 的角度来衡量大概是第二名 Jaguar machine 这个同构系统的 2.5 倍。东京理工学院 (Tokyo Institute of Technology) 研制的异构 Tsubame 2.0 计算机,也即排名第四的 TiTech machine,大概比天河-1A效率高出 50%。这其中的根本原因在于在同构机器中的 CPU是为优化单线程性能而设计的,采用了一系列现代的微处理器优 化技术包括分支预测 (branch prediction),各式各样的投机执行 (speculation),寄存器重命名 (register renaming),动态调度 (dynamic scheduling)以及为优化单线程的延迟而设计的 cache;而相反,GPU 是为优化吞吐率而设计的。通过省掉很多在 CPU 上很常见但是却极其耗能的优化技术,平均对于一个操作而言它能够获得 10 的能源节省。但是这种高效不是没有代价的--单个线程在 GPU 上的性能非常非常得糟糕。

      这种在效率上的区别将在为面向2018年计算而进行的超尺度计算机 (Exascale computers) 设计中被放大。我们甚至只要考虑以下情况,即假设我们能够从工艺发展(更小的晶体管)中得到的 4 倍能耗效率提升,并且在 CPU GPU 上同时获得 4 倍体系结构级别效率提升,那么 CPU 内在的相对低效性将导致最终其 6 倍低效于 GPU。这 6 倍的差距可以导致一个 20 兆瓦(是的没错,我 说的是“兆”瓦)的计算机和一个 120 兆瓦的计算机。如果一年在一兆瓦上花 100 万刀的话,这将是一个巨大的数目。

      那么其间的挑战自然就在于,如何利用异构系统的计算能力去解决影响科学和社会的实际问题而不是仅仅追求 LINPACK 的分数。Bill 举了个例子 说,NVIDIA 对于编程语言比如 CUDA 的投资正在使得程序员可以把以前的旧的单线程代码移植到新平台上--他给了几个例子。一个例子是在医药领 域,GPU 被用于通过减少 X 光扫描次数来减少 CT 扫描的辐射剂量,这将最终导致降低癌症得病率。另一个例子是将 GPU 利用于动态分子模拟上,去模拟表面活 性剂的化学特性并且开发更好的比如香精一类的产品。虽然这些应用当前都只是在少量的 GPU 上跑,但是我预期在接下来的几个月里能够看到一些在 Top500  中那些大规模异构 GPU 机器上运行实际的科学计算代码并且获得令人振奋的结果(Tsubame 的那些哥们儿已经报告了一些这方面的工作了)。

      最后,Bill 谈了一些一个 NVIDIA 正在进行的新的超尺度计算的项目 Echelon。它部分地由 DARPA 的普适高性能计算 (Ubiquitous High Performance Computing, UHPC) 项目资助。NVIDIA 已经和 CrayOak Ridge National Labs 以及 6 个顶尖高校合作来开发高性能低功耗并且可靠的体系结构和编程系统了(译者按,其中这学期给我们上体系结构课的 Mattan Erez 将领导这个项目在 UT 的分支)。Bill 展示了对于未来异构计算系统的展望。他预期能够解决当今 GPU 系统的一些不足比如分离的内存空间和相对低 带宽的连接 CPU GPU I/O 总线。Echelon 的设计将整合一大坨为吞吐率而优化的计算核心和少量的优化延迟的计算核心于单个芯片上,他们共享一 个内存系统。这样的芯片有 20 TeraFLOPs 的性能并且如果把一坨这样的芯片放一起的话可以整成一个 2.6 PetaFLOP 的机架。达到超尺度计算只需要大概几百个这样的机架就好--这其实就和如今的高端集群差不多。再说一遍--这仅仅是一个目前在研的项目, 虽然我预期一些在我这个博客圈里的人会把Bill的介绍当成 NVIDIA 的新品推介广告--哈哈!

      我个人的意见是,Bill 描绘了一幅非常有说服力的对于未来可实现的超尺度系统的蓝图,但是我不认为每个听众都信服。一些我听到的闲谈提到了对于异构系统 可编程性的怀疑。我个人的分析(这个我在下面将提到的 "Round 2" 讨论会上也讲到了)是,我们其实没有别的选择。能耗的限制迫使系统采用优化能耗,面向吞吐率的处理器核与优化延迟的处理器核协同工作的方式。无论是好 是坏,大家都要一起工作来制定一种能够开发这种系统的编程模型,并且保证硬件能够包含支持这种编程模型的机制。

      Round 2 一个关于异构计算系统的研讨会,由 Oak Ridge National Labs Jeff Vette r组织。AMD Chuck Moore 给出了一个我认为是非常有远见的对于什么是异构计算什么不是的定义。异构计算不能是所谓的 "Frankensystem",也就是那种随意地把 不同的硬件和软件坨在一起的系统。也不能是一粒拥有神奇的能耗或者性能表现的子弹。它也不会轻而易举地解决高性能计算所面临的功耗/性能/可编程性/ 战。它是一种促进不同子系统之间通信的系统框架。更进一步,它必须能让菜鸟编程员轻松地利用专用的或者可编程的功能。我感觉到讨论会达成了一个共识,也即 异构计算平台的下一步在于把加速器 (accelerator) 提升为计算系统中的一等公民。AMD 已经很清楚地把这个问题的硬件一端揽入怀中--通过他们最近发布的 "Fusion" 芯片。然而,大量的挑战仍然存在于 软件和编程之中。NERSC 的领导 Kathy Yelick 通过展示她的观察来强调了这些挑战。她认为在向超尺度前进的征程中一定会有一个从 MPI/MPI+OpenMP 出发的编程模型。她不相信整个 圈内会容忍两个编程模型的存在,我们最好赶紧搞定这个模型,越快越好。

      Round 3 一个由弗吉尼亚理工 (Virginia Tech) 计算机系的 Wu Feng 副教授,同时也是绿色 Top500 排名的维护者,组织的讨论会,主要议题是异构计算中的 3P 问题:性能 (Performance),功耗 (Power) 和可编程性 (Programmability)AMD Mike Houston 举了一个强有力的例子说,应用程序通常会开发交织式的并行性 (braided parallelism),也就是有很多条件数据的并行性--讨论会上大多数人都同意这个观点。讨论会上最活跃的家伙是来自 Intel Tim Mattson。他强力宣称可编程性的重要性远超过性能和功耗。如果你不能为一台机器编程,谁会在意它的峰值性能和理论效率?他甚至毫不掩饰他对于开源软 件标准的立场,任何一个单独的公司,包括 Intel,都不应该控制编程语言。这番言论后来演变成了 OpenCL PK CUDA 的讨论了。虽然我不想一一点出这场争论中的主角,但是确实有不少人对于 Mattson 提到的危害进行了一番慷慨激昂的演说。其他人的观点是这个技 术仍然只是在草创阶段,匆忙地在成熟之前制定标准只会抑制创新。虽然有不同的争论,但是与会这都热忱赞成软件乃是最大的挑战(有人感觉到了这个主题么?)

      这俩讨论会都太火了,简直没有立锥之地,房间几乎要爆了,参与的人也很不错。Jeff Vetter 尝试了一个听众反馈系统,能够让大家通过手机短信反馈调查问卷的问题。一旦大家都熟悉了这种听众参与的方式,我觉得这招在以后的讨论会都会显得比较酷。

      今天到底为止。

      ---------------大家好,我是分割线---------------

      1. 整个翻译完了我回顾一下其实这不是一个特别有技术营养的文章,毕竟只是个人见闻。而且谈的都是老汤戏了。但是如果大家对这个话题感兴趣,这个文章读起来也会比较有意思。因为讲的细节很少,这种宏观的讨论或许对把握大方向有好处。具体的细节,还是去读 paper
      2. 下次挑选文章的时候基本上不会有这样的文章了。我本来预期会是一篇科普性质的文章,毕竟是在 CACM 上的,孰料其实是一篇游记。我也放弃了翻译Steve其余两篇游记的计划。但是应该还会在 CACM 上选。
      3. 大四最后一个学期做了一些异构架构的事情,下个学期也很可能做这方面的事情。让我们擦亮眼睛看看会如何演化吧。