大多数计算技术专家都承认,全球数据每两年会翻一番。预计到2020年,对那些与人工智能(AI)相关的高级应用(如机器学习、机器人技术、自动驾驶和分析以及金融市场)来说,数据集将超过21ZB(zettabyte)或更多。
这些类型的应用都依赖于大数据,这就需要一些实时计算非常小、但层级很多的软件算法,但如今的多核处理器和架构在性能和效率方面不能很好地满足这些算法的需要。
直到21世纪初,计算机性能与处理器的时钟频率相关,根据摩尔定律,每18个月频率会增加一倍。2005年后,摩尔定律显示,约每隔18个月处理器核数翻一番。传统观点认为,计算性能的进步将来自于向传统处理器添加更多的核。然而,如图1所示,最终结果却发生了边际效益递减的情况。
图1:多核CPU性能并未持续上升。(来源:CORNAMI)
为提高传统软件算法的性能而添加的核越多,增量增益越小(有一些值得注意的例外)。因此,核数量止步不前。每代的晶体管数量增加一倍,多出的晶体管用来使“少量”核的速度稍微快一些,而不是用来增加更多的核。晶体管资源的指数增长被浪费了,只能给我们带来性能上小的线性增益,如图2所示。
图2:大数据和机器学习的处理需求要求我们更有效地使用晶体管预算。(来源:CORNAMI)
需要处理的数据量正在以指数速度增长。目前这一代“云”由充满“少量核”的服务器的海量机架组成。其结果是大量的网络服务器正在造成大规模的数据中心蔓延,所有这些都导致全球用电量和碳排放量大幅增加。
关键的是,对大数据和机器学习工作负载的检查表明,它们与现有处理器数十年来设计和优化的工作负载大不相同。大数据/机器学习代码大小以kLOC(千行代码)为单位,而传统软件(考虑你最喜爱的办公套件,甚至最喜爱的操作系统)是以mLOC(百万行代码)为单位进行度量的。例如,在中国科学院为SPARK应用框架提供的流行的BigDataBench 3.2上的一个简单的LOC grep(Globally search a Regular Expression and Print/正则表达式全局搜索并打印,一种强大的文本搜索工具),就涵盖了十几个不同的基准测试,显示总计不超过1000行SCALA代码的累计kLOC。Yahoo!的 Streaming Benchmark,则少于300行的SCALA代码。谷歌的TensorFlow MNIST,整个教程有多个副本,有超过1000行python代码。
主要观察结果如下:
1.我们需要在大数据/机器学习中处理的工作负荷是独一无二的、每个都很小,而且性能体现在在许多,许多服务器之间复制这些代码。
2.需要处理的数据量每年呈指数级增长,本质上是流式传输,并具有一些实时要求(考虑自动驾驶汽车或即时移动广告)。
3.由于硅供应商的研发,晶体管数量仍然呈指数级增长。
假设:需要一种适合目前工作负荷的新处理架构,它应能提供一种可扩展、大规模并行、海量核的方法。让我们使用晶体管预算,通过添加大量核来提供更多计算,而不是试图加速一些核。
硅谷的一家人工智能高性能计算公司CORNAMI正在处理这些过程问题,并将计算性能提升到非凡水平。CORNAMI利用并发技术开发出获得专利的新计算体系架构,该技术可以独特地改变软件性能并降低功耗、延迟和平台尺寸。
其结果是在每个处理核都具有独立决策能力的大规模并行体系架构,穿插着高速存储器,并且所有这些都通过生物启发式(biologically-inspired)网络互连以产生可扩展的海量核。该体系架构基于CORNAMI开发的独特结构,称为TruStream计算结构(TSCF,TruStream Compute Fabric),可跨多个芯片、电路板和机架进行扩展,每个核可独立编程。
通过使用TruStream编程模型(TSPM,TruStream Programming Model),多核处理器资源被抽象为共同的同质核池。TruStream在软件和硬件上均实施,并可在TruStream计算结构中运行。程序员可通过嵌入到更高级别标准语言中的CORNAMI的TruStream控制结构轻松实现并发性。
最近来自微软的关于其卷积神经网络加速器、谷歌关于其用于神经网络加速的张量处理单元(TPU),以及来自NVIDIA的关于其深度学习GPU的Volta的发布都揭示了加速机器学习算法的类似方法。
要加速的算法都是三维滤波器的变体(图3)。重型升降机(消耗CPU/GPU最大算力或硅面积的算法)是种三维卷积滤波器——这是卷积神经网络(CNN)的核心和灵魂。
图3:卷积神经网络(CNN)显示了3D Convolution + 3D ReLu + 3D Pooling(图片来源于Gao,F;Huang,T;Wang,J; Sun,J;Hussain ,A;Yang,E的《用于极化SAR图像分类的双分支深度卷积神经网络》一文的知识共享署名许可协议,《应用科学》2017,7,447)。
为了加速这些算法,使用了二维硅结构—— 一种称为脉动阵列(systolic arrays)(《用于VLSI的脉动阵列》,H.T.Kung和Charles E.Leiserson,1978)的硅加速器。图4显示了要相乘的两个简单的3×3矩阵;图5显示了将执行乘法的3×3乘法累加单元的脉动阵列。
图4:3◊3矩阵乘法。(来源:CORNAMI)
图5:执行流式矩阵乘法和累加的3◊3元素的脉动阵列(来源:CORNAMI)
例如,输出矩阵元素C11包含在A和B输入数据完成流入之后的结果A11•B11+A12•B21+A13•B3。较大维数的阵列允许发生大量并行操作;阵列元素之间更复杂的互连增加了带宽;每个元素更复杂的功能允许执行卷积和其它功能;而更复杂的控制电路允许结果流出,因为更多的数据流入和更多的计算被执行。
这些是用于生产部件的技术。消除复杂性及核心思想很简单。请注意,输入矩阵按照特定的顺序流入阵列的左侧和顶部,并将结果从阵列中流出。一个脉动阵列的属性(即能够连续大量数据流入和流出的结构;同时操作所有元素;以及中间值保存在脉动阵列内部的事实;并且不需要被“保存”到内存中)提供所需的性能。
基于上述情况,我们现在可以得出以下几个关键见解:
• 脉动阵列的每个元素都是元胞自动机的一种形式,它使用简单的规则对其周围的数据作出反应。
• 微软、谷歌和NVIDIA高性能机器学习硅部件中的脉动阵列(如本文前面所讨论的)将阵列视为固定功能硅加速器,其中尺寸、元件功能和互连都是ASIC掩模组创建完成时就固定了的。
• 用于机器学习的新型硅加速器的快速发布速度表明,算法仍处于高度变化中。几乎每周都会发布新的、更高效的新处理方法。在硅上运用机器学习算法后,它会在下周的公告中迅速就变得过时。
假设:如果我们允许编程人员通过软件来定义任何脉动阵列的维度、功能和互连性,该怎么办?也就是说,要保持机器学习所需的高性能,这是脉动阵列的一个副作用;但允许软件程序员通过完全允许在软件中进行更改来跟上新算法的发展。
另外的好处是,这种软件方法应用范围相当广泛,远远超出了机器学习的范围,其中,对二维或更高维阵列的元素(单元、像素、体素),及其邻元素进行操作。应用范围举例如下:
• 机器学习
• 图像处理
• 压缩/解压缩
• 编码/解码
• 三维(3D)建模
• 流体动力学
• 有限元分析
• 密码学
• 纠错编码
• 建模物理现实
让我们来看一个前面提到的软件定义脉动阵列方法的完整实例,该实例使用了TruStream编程模型(TSPM),以在海量核TruStream计算结构(TSCF)上执行软件。为了说明将TruStream应用到这些问题中的技术,我们选择了生命游戏元胞自动机(Game of Life cellular automaton),它由二维方格细胞组成,每个细胞只与以自身为中心的相邻八格细胞进行交互。几乎所有的软件编程人员都应该很熟悉这点,并且很容易就可以说明这些机制。当在TSCF上运行生命游戏的TSPM程序时,每个生命游戏细胞都运行在其自己独特的TSCF核上。
自从亨利福特时代以来,组装脉动阵列的问题与工厂设计师一直在处理的问题非常相似。工厂建构师将问题看作是组织一系列实体(机器、机器人和工人)的问题,这些实体通过从一个实体流向另一个实体的小部件流进行交互。当这些建构师绘制其工厂图时,他们绘制框图,而不是流程图。然而,在进行工厂设计时,流程图的作用是:它们非常适合描述单个机器、机器人和工人的顺序行为。总结来说:
确定工人执行任务和布置工厂的顺序是两个根本不同的活动。
正是这些观察激发了我们对计算的看法:计算机是组装数据值的工厂;激发了我们对编程的看法:程序的某些部分可最容易且自然地表示为流程图,程序的其它部分最容易且自然地表示为框图。或者等价地:程序的某些部分在TSPM线程域中最容易和自然地表达;程序的某些部分在TSPM流域中最容易和自然地表达。
根据这些,我们创建了TruStream编程模型,该模型基于五个C++类,如下所示:
图6:构成C++的TSPM的C++类。(来源:CORNAMI)
为了更直观地了解这些类,请参阅图7和图8,它们提供了五种TruStream对象的图形表示。
图7:TruStream对象。(来源:CORNAMI)
图8:输入和输出流。(来源:CORNAMI)
图7显示了TruStream编程模型的两个关键特性,如下所示:
• TruStream拓扑可能是循环的(或非循环的)。
• 通过嵌套streamModules创建分层拓扑。
TruStream编程模型有三个独特属性,如下所示:
• TSPM代码分为两个域:线程域和流域。
• TSPM仅在流域中表示并行性。
• TSPM依靠单一机制来同步线程:TruStreams。
第一个属性体现了关注点分离的设计原则,允许程序员专注于每个领域内的单独关注。
• 在线程域,程序员处理严格的顺序问题。
• 在流域,程序员处理流和流上的转换。
由于这种关注的分离,线程域程序员和流域程序员都不担心多线程或将代码映射到单个处理器内核。
第二个属性意味着线程域程序员(编写顺序代码的程序员),不必处理并行性。这与传统的并行编程方法显着不同。
第三个属性意味着线程域程序员和流域程序员都不必处理基于线程的并行性结构引起的同步问题(参见图10)。然而,尽管没有这些构造,TruStream程序员可以访问所有形式的并行。
在下面的生命游戏例子中,整个TSPM程序由四个C++类的定义组成,如图9所示:
图9:构成生命游戏的类(来源:CORNAMI)
图10:在TruStream编程模型中构造NOT(来源:CORNAMI)
TruStream计算结构是一个可扩展的海量核处理器,包含处理核和片上SRAM。所有核都可独立编程,并且可并行进行独立决策(与现代图形处理单元不同),并且该架构可以跨越多个芯片、主板和机架进行扩展。像大多数程序员不会过度关注他们使用的RAM数量一样,TruStream程序员也不必过于关心他们使用的核数量。
TSCF和TSPM之间的连接包含在以下三个属性中:
• TruStream程序中的每个threadModule都有自己的TruStream计算结构核。
• 在TruStream计算结构核中运行的唯一代码是封装在threadModule中的线程域代码
• TruStream程序中的每个streamModule在TruStream计算结构中配置一个TruStream拓扑。
TruStream计算结构的主要特性概括如下:
• TSCF针对TruStream编程模型进行了优化,因此TSCF(如TSPM)支持所有形式的并行。
• TSCF对TruStreams提供硬件支持、对TruStream提供gets和puts支持,使TSCF能够非常高效地运行TSPM程序。
• TSCF中唯一运行的代码是应用代码!仅此而已。没有列出结构中运行的11个膨胀代码(bloat code)。
• TruStream计算结构中的线程等待输入数据和输出空间。除此之外,线程不会等待。
• 每个TSCF核最多支持一个线程,因此不存在上下文切换。这意味着不需要调度程序(scheduler)或分发程序(dispatcher)。
• TSCF性能来自并行性,而不是蛮力的速度,因此我们有优化TSCF的能源效率的优势。
• 由于芯外(off-die)操作是性能杀手,TSCF提供大量片上SRAM。
每个TSCF核都有自己的存储器端口,因此TSCF提供特别(高)的聚合存储器带宽。
总之,这些特性导致:(1)延迟显着降低;(2)性能显着提高;以及(3)计算能力显着增加。
图11:未在TruStream 计算结构中运行的代码(来源:CORNAMI)
生命游戏,又称生命棋,是由英国数学家约翰·何顿·康威(John Horton Conway)于1970年发明的元胞自动机。
该“游戏”是一款零玩家游戏,这意味着它的演变取决于它的初始状态,不需要进一步的输入。通过创建初始配置并观察它的演变方式、或通过创建具有特定属性的模式(对于高级“玩家”)来与生命游戏进行交互。
规则:
生命游戏的宇宙是一个方形细胞的无限二维正交网格,每个方格处于两种可能的状态之一,即活着或死亡(或“有人居住”或“无人居住”)。每个细胞与它相邻的八个细胞相互作用,这八个细胞是水平、垂直或对角相邻的细胞。在每个介入(step-in)时间,都会发生以下转换:
就该定义,我们做两个简单修改,如下所示:
• 下面的TruStream程序实现了一个8◊8单元网格,而非正方形单元的无限二维正交网格。
• 阵列的南北和东西边缘是环绕的,以便当经典的生命游戏滑翔机(glider)到达阵列的东南角时,它会瓦解,仅在阵列的西北角重新组装。
在下面的章节中描述了用于生命游戏的TruStream程序,假定清单1中显示了#includes和#defines。
1.
清单1:#includes和#defines(来源:CORNAMI)
单元线程模块
清单2中所示的单元线程模块类实现了上述的生命游戏单元,包括四个转换规则。
清单2:单元格线程模块(来源:CORNAMI)
GameOfLifeArray流模块
GameOfLifeArray流模块(清单3)构建了生命游戏阵列:
清单3:GameOfLifeArray流模块。(来源:CORNAMI)
显示线程模块
显示线程模块(清单4)印出GameOfLifeArray流模块的连续几代的单元状态。
清单4:显示线程模块(来源:CORNAMI)
GameOfLife流模块
GameOfLife流模块(清单5)将GameOfLifeArray连接到显示器以构建生命游戏。
清单5:GameOfLife流模块(来源:CORNAMI)
主要功能
我们现在看我们的生命游戏程序中最简单的部分:运行它。
清单6:main()函数。(来源:CORNAMI)
如清单6所示,运行一个TruStream程序包含三个步骤:
GameOfLife GOL;
GOL.run();
此次调用使TruStream计算结构的65个核运行10,000代生命游戏程序——GOL阵列的64个核和用于显示的一个核。在生命游戏输出(图12)中,我们看到了经典的“生命游戏”滑翔机(a)在世代0到16中向东南方向滑行;(b)在世代17到26中分解;(c)在第27代中重新组装;(d)在第32代中恢复到初始状态。
GOL.wait();
该调用导致main()函数等到程序完成。
步骤3完成后,main()返回。前33代输出如下所示。
图12:前33代输出(来源:CORNAMI)
TruStream技术重新定义了计算的含义。在过去的70年中,一直以线程为中心的观点已一去不返。取而代之的是这样一个模型:线程仍扮演一个角色,但是个支持角色(可以完全消除线程;例如,用纯功能语言编写的功能代码替换顺序线程域代码,以及用栈机替换冯诺依曼核)。
该技术最显着的特点是:(a)将代码分成两个域:线程域和流域;(b)仅在流域中表达并行性;以及(c)依赖单一机制(TruStreams)用于同步线程。
这些功能有很多好处,其中主要有以下几点:
•在软件内快速构建任意多维脉动阵列并使其在核计算结构上运行的能力。你可以实现当今最喜欢的机器学习算法,并且当更好的机器学习算法出现时,就取而代之。当系统工作负荷发生变化时,软件可以实时更改脉动阵列的大小和性质。需要结合机器学习功能执行复杂和任意的控制功能吗?编码它!我们无论怎样强调软件灵活性的优势都不过分。利用用于机器学习的高性能硅加速器,你会被ASIC流片时制定的设计决策所束缚,而且硅加速器仍然需要访问通用处理器核,以便控制决策。
•可任意扩展的多核架构。大多数多核方法都有一个集中式资源(例如调度程序或分发程序)作为限制系统规模的瓶颈。在TruStream计算结构中,没有这样的瓶颈。一旦TruStream拓扑下载到TSCF并开始运行,拓扑中的每个线程模块都是独立的。它从输入流获取数据值、执行计算、并将数据值放入输出流中。仅此而已。没有运行时间调度或分发,并且没有同步原语(synchronization primitive)——超越TruStreams。而且,由于每个线程模块都有自己的核,所以没有上下文切换。多个IC可以连接在一起构建更大的计算结构;机架中的多个服务器可以连接在一起;并且多个机架可以结合在一起来处理更大的工作负荷。
•对于大数据和机器学习应用,优势转向拥有越来越多的更小的核,而不是试图尽力提高大型传统处理器核的性能。技术节点的变化通常使你可将放在同一尺寸芯片上的晶体管数量加倍。在今天的技术节点实践中,这意味着你会得到另外几十亿只晶体管。传统方法将利用这些晶体管并将其转化为15%至30%的性能增益。现在,你可以将它们转换为额外的4,000个处理器核。
关于作者:
Paul Master是CORNAMI公司的联合创始人兼CTO。 Frederick Furtek是CORNAMI公司的联合创始人兼首席科学家。
本文为《电子工程专辑》6月刊杂志文章,版权所有,谢绝转载
关注最前沿的电子设计资讯,请关注“电子工程专辑微信公众号”。