从程序员的角度来看,硬件和软件之间的区别正在变得模糊。随着程序员努力满足当今系统的性能要求,他们将面临越来越大的需求,以利用替代计算元件,例如 GPU(图形处理单元),它是被颠覆用于数据并行计算的显卡11,以及 FPGA(现场可编程门阵列)或软硬件。
当前主流计算架构的迭代基于缓存一致性的多核处理器。这种主题的变体包括英特尔的实验性单芯片云计算机,它包含 48 个非缓存一致性的核心。然而,这条路径是由频率缩放的结束所决定的,而不是由程序员希望如何编写软件的需求所驱动的4。可用于为此类多核系统编写并发和并行软件的传统武器主要基于为编写操作系统而开发的抽象(例如,锁和监视器)。然而,这些不是用于编写并行应用程序的正确抽象。
有更好的方法来烘烤所有的沙子。从延迟和能耗的角度来看,更好的方法是使用各种各样的处理元件协同工作,并进行调整以执行不同类型的计算和通信,而不是组合许多看起来像常规 CPU 的元件。大型粗粒度任务适合在多核处理器上实现。数千个细粒度数据并行计算适合在 GPU 上实现。需要以极高性能或降低能耗运行的不规则细粒度任务适合作为在 FPGA 芯片上运行的数字电路实现。未来是异构的。
这种异构系统的出现挑战了硬件和软件设计过程之间已经建立的舒适区分。CPU 的 ISA(指令集架构)充当了一个方便的接口层。软件行业的前提是只有一种硬件(CPU)和一个标准化的接口(ISA)。这使得硬件行业能够不断创新一系列符合固定 ISA 接口的微架构。当寻求绝对最大性能或降低能耗的程序员转向 GPU 和 FPGA 等替代处理元件时,这种舒适的界限正在被侵蚀。
我们很可能看到异构计算系统部署的一个地方是在云中,我们可以想象机架不仅填充了多核处理器,还填充了 GPU 和 FPGA。亚马逊已经创建了弹性计算云,它允许在 GPU 上执行计算。某些类型的计算可以在 GPU 和 FPGA 上以比 CPU 更好的性价比执行。随着能源使用成为数据中心增长的更大限制因素,部署异构架构以帮助减少延迟和能耗将是不可避免的。这些系统将需要编程模型和运行时基础设施,以便根据计算需求和非功能性需求(能耗与延迟)将计算重新映射到不同类型的处理硬件。这些系统甚至将开辟根据能耗而不是时间或周期收费的机会。
为了使云中的异构计算成为现实,仍然有许多技术挑战需要克服:例如,如何虚拟化 GPU 和 FPGA 计算,以便可以将它们移动到不同的物理资源,以及如何防止安全漏洞9。
异构系统引入的另一个挑战将是数据结构的设计,这些数据结构适合在多核处理器和通过复杂内存层次结构或片上网络连接的异构计算元件上使用。这将迫使我们重新思考堆栈和队列等结构,而是考虑无序的并发结构,这些结构允许更大的内存访问和布局灵活性12。
现代异构系统正在朝着引人入胜的计算可能性的未来发展。今天的系统正处于实现该目标的各个发展阶段,包括改进允许并行处理的架构,创新现有编程语言,以及将语言可移植性扩展到 GPU、AVX(英特尔高级矢量扩展指令集)和 FPGA。
当今最流行的异构计算资源是 GPU,它提供了一种具有高聚合内存带宽的架构,并且能够执行比传统处理器更多的数据并行操作。其他异构计算元件(如 FPGA)也可以有效地实现数据并行操作,并支持高速不规则操作,例如以“线速”(即,在数据流经高速网络时实时)处理 XML 查询。
对新的数据并行计算元件的利用自然而然地借鉴了高性能科学计算中并行编程的经验(例如,MPI 和 OpenMP)。许多有用的应用程序不是数据并行的,但允许其他类型的并行化(例如,异步通信线程,其中每个线程执行不同的任务)。
为了有效地利用异构计算,程序员需要超越如何并行化嵌套的问题for循环,并考虑如何在现代应用程序的高度不规则结构中尽可能多地并行计算。使利用不规则并行性更容易的技术包括 STM(软件事务内存)和 AME(自动互斥)1。
尽管 GPU 可以为数据并行算法提供显著的性能提升,但即使使用特殊的 GPU 编程语言和系统(如英伟达的 CUDA(计算统一设备架构))10,它们也远非易于编程。为了从 GPU 获得良好的性能,人们会经历一次“回到未来”的体验,即使用昨天的技术对明天的硅进行编程——即显式数据放置、数据移动和数据同步。现代 GPU 架构具有需要显式编程的内存层次结构,才能获得良好的性能。
今天,大多数有效使用 GPU 的人都要经历陡峭的学习曲线,并且被迫使用特殊的 GPU 编程语言来接近机器。程序员真的需要一套特殊的语言来为 GPU 编写数据并行程序,以及另一套语言来为多核处理器编写数据并行程序吗?在高层次的抽象中,手头的任务在两种情况下都是相同的。
软件行业正在通过向现有语言添加创新来应对多核系统的出现,以帮助表达并发和并行计算。然而,在 GPU 上使用数据并行计算无法等待 C++ 等语言被修改以更好地支持并行性,因此开发了 CUDA 等系统来填补空白。
随着 C++ 扩展以支持数据并行性(例如,通过引入数据并行for循环),将会有新的 C++ 编译器后端可以针对 GPU(并最终针对 FPGA),今天用 CUDA 编写的一些程序将在未来用 C++ 和其他主流语言(如 Java 和 C#)的数据并行版本编写。然而,为了从 GPU 中提取最佳性能,仍然需要使用 CUDA 等暴露低级架构特性的系统;但对于许多类别的算法和用户来说,来自数据并行传统语言的更高级别编译路径就足够了。最终,我们将需要设计新的语言,为现代计算系统提供有效的内存模型2。
为了满足当今对可以针对异构系统的更高级别数据并行编程系统的需求,人们可以关注微软的 Accelerator 系统13。它允许编写某些类型的数据并行描述,然后可以在三个不同的目标上执行:GPU、使用 SSE3 矢量指令的多核处理器和 FPGA 电路,如图 1 所示。(可以从 http://research.microsoft.com/en-us/projects/Accelerator/ 下载 Microsoft Accelerator。)
总的来说,我们不能指望设计一种语言或系统来编程异构系统,使我们能够将单个源代码编译成在 CPU、GPU 和 FPGA 等完全不同的计算元件上的高效实现。这种并行性能可移植性很难实现。然而,如果问题域受到充分的约束,则可以从单个源描述中获得良好的并行性能。Accelerator 通过约束用于并行编程的数据类型(到不能显式索引的整个数组)以及提供一组受限的并行数组访问操作(例如,按顺序、反向、带步长、移位、转置)来实现这一点。
并非所有类型的数据并行算法都适合(例如,矩阵求逆不符合此模型)。然而,对于许多类别的算法(例如,模板式计算8),Accelerator 系统使得可以将单个描述编译到三种非常不同的硬件类型,并获得良好的性能。人们总是可以使用 CUDA、SSE3 内在函数或 Verilog 制作更快的实现,但这种性能改进是以显著更高的设计成本为代价的。
Accelerator 的一个关键方面是它不是一种新语言。该系统就像一个库一样工作,可以从任何支持在 Windows 下与 C 调用接口链接的语言中使用。使用 Accelerator 系统的应用程序已经用多种语言编写,包括 C++、C#、F# 和函数式语言 Haskell。
Accelerator 是 EDSL(嵌入式领域特定语言)的一个示例。Accelerator 系统为用户提供了一种抽象编程语言,该语言编码了数组和整个数组操作以及某些内存转换的概念。这种抽象语言嵌入在传统的具体语言中,抽象语言的程序以具体语言的数据结构表示。这种技巧是编程异构系统的宝贵技术,它允许您以语言无关的方式编写数据并行描述,并交叉编译到各种硬件架构。
考虑执行两个数组的逐元素数据并行加法的任务:[1, 2, 3, 4, 5] 和 [6, 7, 8, 9, 10]。这个非常简单的 Accelerator 程序在此处显示为一个 C++ 程序
#include <iostream> #include "Accelerator.h" #include "DX9Target.h" using namespace std; using namespace ParallelArrays; using namespace MicrosoftTargets; int main() { // Create a GPGPU computing resource DX9Target *tgtDX9 = CreateDX9Target(); // Declare some sample input arrays float xvalues[5] = {1, 2, 3, 4, 5} ; float yvalues[5] = {6, 7, 8, 9, 10} ; // Create data-parallel versions of inputs FPA x = FPA(xvalues, 5) ; FPA y = FPA(yvalues, 5) ; // Specify data-parallel computation FPA z = x + y ; // Computation does not occur here... // Allocate space for the result array float* zvalues = (float*) malloc (5 * sizeof(float)) ; // Execute the data-parallel computation on the GPU tgtDX9->ToArray(z, zvalues, 5); // z = x + y is now evaluated // Write out the result for (int i = 0; i < 5; i++) cout << zvalues[i] << " " ; cout << endl ; return 0 ; }
当执行此程序时,会产生以下输出
这个常规的 C++ 程序可以使用未修改的 Visual Studio 编译器编译,并与 Accelerator 库链接。当它执行时,它会在主机处理器上通过 JITing(使用即时编译)在运行时生成 GPU 代码(使用 DX9 系统),将生成的代码和数据传输到 GPU 执行,然后将结果传输回主机进行显示。JITing 模型允许系统隐藏有关 GPU 代码生成和与 GPU 硬件通信的许多低级细节。重要的是要注意,数组的数据并行加法x和y是通过使用“+”运算符的重载定义来指定的,该运算符在堆中构建一个数据结构来表达预期的计算
此代码以“纹理内存”表示输入和输出数据并行数组,并对这些数组使用数据并行加法指令。Accelerator 系统的用户完全不受计算的图形级别视图的影响。
要以 SSE3 矢量指令在多核处理器上运行相同的计算,并在多个处理核心之间拆分数据,您将编写完全相同的程序,但指定不同的目标。为了强调 Accelerator 的语言中立性,此示例将源语言切换为 C# 以用于多核 SSE3 版本
using System; using Microsoft.ParallelArrays; namespace AddArraysPointwiseMulticore { class AddArraysPointwiseMulticore { static void Main(string[] args) { var x = new FloatParallelArray (new[] {1.0F, 2, 3, 4, 5}); var y = new FloatParallelArray (new[] {6.0F, 7, 8, 9, 10}); var multicoreTarget = new MulticoreTarget(); var z = x + y; foreach (var i in multicoreTarget.ToArray1D (z)) Console.Write(i + " "); Console.WriteLine(); } } }
当此程序运行时,它会动态生成 (JIT) SSE3 矢量指令,并将数据拆分到多个核心,然后在每个核心上启动矢量指令,以提供与 GPU 版本完全相同的结果。
当多核 SSE3 实现或 GPU 实现无法满足性能要求时,您可以尝试通过编写相同的并行计算描述并指定使用 FPGA 目标来生成 FPGA 实现。同样,为了强调 Accelerator 的语言中立性,此示例将源语言切换为 F#
open System open Microsoft.ParallelArrays let main(args) = let x = new FloatParallelArray (Array.map float32 [|1; 2; 3; 4; 5 |]) let y = new FloatParallelArray (Array.map float32 [|6; 7; 8; 9; 10 |]) let z = x + y use fpgaTarget = new FPGATarget("adder") fpgaTarget.ToArray1D(z)
请注意,此示例未写出在 FPGA 芯片上执行数据并行描述的结果。我们目前无法支持 FPGA Accelerator 目标的 JITing 模型,因为将硬件描述处理为 FPGA 编程比特流(FPGA 电路的机器代码)的设计工具通常需要很长时间才能执行(几十分钟甚至几小时)。此目标以离线模式工作,并生成 VHDL(VHSIC 硬件描述语言)硬件描述,该描述存储在文件(adder.vhd)中,可以用作 FPGA 供应商提供的特殊设计工具的输入。
Accelerator 程序的一个更真实的示例是卷积器,它计算流或图像上的加权平均值,如图 2 所示。实现此算法的一种直接方法是用嵌套for循环来表示计算,这些循环使用显式数组索引来捕获滑动窗口的概念。然而,对于想要生成并行实现或可以针对异构处理核心或数字硬件集合的系统来说,这是一个糟糕的起点,因为很难将任意数组索引操作映射到各种目标上的高效内存访问操作。
表达这种计算的更好方法是使用整个数组操作与显式内存访问转换相结合。内存转换操作的一个示例是shift,如图 3 所示。此操作采用输入数组x并生成一个输出数组,该数组可以向右 (-1) 或向左 (+1) 移位。
图 4 显示了移位操作的应用,该操作用于描述输入数组的连续移位版本,之后并行执行整个数组乘法,然后进行并行归约(加法操作)以产生卷积输出。
在 Accelerator 中,卷积操作的整个数组描述可以表示如下
using Microsoft.ParallelArrays; using A = Microsoft.ParallelArrays.ParallelArrays; namespace AcceleratorSamples { public class Convolver { public static float[] Convolver1D(Target computeTarget, float[] a, FloatParallelArray x) { var n = x.Length; var y = new FloatParallelArray(0.0f, new [] { n }); for (int i = 0; i < a.Length; i++) y += a[i] * A.Shift(x, -i); float[] result = computeTarget.ToArray1D(y); return result; } } }
此描述在“目标”上参数化(即,它可以用于生成多线程 SSE3 指令、GPU 代码或 FPGA 电路,具体取决于computeTarget的实际值。请注意,权重数组a是一个常规的 C# 数组,因为这表示编译时常量,而不是仅在运行时才知道的数据。另一个数组参数x具有不同的类型FloatParallelArray。这表示一个数据并行数组,它可能与主机 C# 程序位于不同的地址空间中(例如,在 GPU 的内存库或 FPGA 芯片上的嵌入式内存中)。这些数组不允许显式数组索引,而是提供内存转换操作,例如Shift.
为了说明可以从这种方法中期望获得的性能改进类型,将二维卷积器计算的 Accelerator 版本与编写为两个可分离通道的顺序版本进行了比较。
Accelerator 版本通过应用两个一维卷积来工作,并将用于此算法的数据并行执行的特定目标作为参数
public static float[,] Convolver2D(Target computeTarget, float[] a, float[,] x) { var xpar = new FloatParallelArray(x); var n = x.GetLength(0); var m = x.GetLength(1); var zpar = new FloatParallelArray(0.0f, new[] { n, m }); var shiftBy = new[] { 0, 0 }; for (var i = 0; i < a.Length; i++) { shiftBy[1] = -i; zpar += a[i] * A.Shift(xpar, shiftBy); } shiftBy[1] = 0; var ypar = new FloatParallelArray(0.0f, new[] { n, m }); for (var i = 0; i < a.Length; i++) { shiftBy[0] = -i; ypar += a[i] * A.Shift(zpar, shiftBy); } return computeTarget.ToArray2D(ypar); }
顺序版本在一台配备两个英特尔至强 E7450 处理器的计算机上运行,每个处理器的时钟频率为 2.4 GHz。该机器有 32 GB 内存,运行 Windows Server 2008 R2 Enterprise。Accelerator 版本在同一台机器上使用 SSE3 多核目标运行,使用两个不同的显卡测试相同的代码:ATI Radeon HD5870 和 Nvidia 470 GTX,使用 DX9 目标。卷积的输入矩阵设置为 8,000 x 8,000,实验改变了卷积核的大小。图 5 显示了相对于顺序基线版本实现的加速。每个 Accelerator 实验的执行时间都包括端到端时间,该时间衡量 JITing 和数据移动到 GPU 和从 GPU 或到 SSE3 情况下的线程本地状态和从线程本地状态移动的成本。
图 5 还显示,随着卷积核变大,SSE3 多核目标和 GPU 目标都显示出性能的提高。然而,缓存效应导致 SSE3 多核目标的加速在内核大小增长到大于 40 后下降。此实验表明,使用可以映射到两个非常不同的目标的单源描述以产生有意义的性能改进是可行的。
设计描述的关键方面是能够以合适的抽象级别描述内存转换操作。对内存组织和访问做出过多假设(例如,随机数组索引)的描述很难或不可能移植到具有完全不同的内存访问经济性的其他架构。
Shift是一个强大的内存访问抽象,因为它揭示了要重用哪些信息,因此值得缓存、存储在寄存器中或放置在 GPU 上的本地共享内存中(图 6)。例如,当 FPGA 目标用于实现卷积器时,移位操作用于推断延迟(和反延迟),这些延迟允许您访问每个数据项一次,但使用三次。(在实际实现中,添加了额外的延迟以消除反延迟,这在现实世界中很难获得。)对于二维卷积器,这种优势更加明显。移位运算符引入的延迟可以重新分配到电路中,以自动产生卷积器的转置实现(如图 7 所示)。这特别适合 FPGA 技术,因为有大量的寄存器用于实现流水线延迟。此电路的典型 FPGA 实现产生一个延迟约为 5 纳秒(对于整数值)的系统,这允许每秒卷积 2 亿个元素。许多这样的卷积器可以放置在 FPGA 电路中,并且每个卷积器都可以并行运行。
Accelerator 模型仅限于将单个描述完全映射到多个目标之一。一个自然的扩展是想象一个系统,该系统将单个数据并行描述编译到处理元件的混合体上。例如,某些子表达式可以映射到 GPU 硬件,而另一些子表达式可以映射到 FPGA 硬件,并且编译过程还将生成协调不同类型硬件元件之间的数据移动和协调其执行所需的软件。此功能对于为给定函数生成一系列代表不同性价比点或不同能耗/延迟权衡的实现非常有用。
通过允许计算以透明的方式从一种类型的处理硬件(例如,GPU)迁移到另一种类型(例如,FPGA),可以将单个计算映射到一组协作的异构处理元件更进一步。
将程序转换为电路并不是一种光荣的炼金术形式,并且未能产生许多开发人员想要的东西(一种真正将真实软件转换为电路的技术)。相反,它仅仅为数字设计师提供了编写高度程式化的电路描述的能力,这些描述与低级寄存器传输级描述只有一步之遥,这些描述通常以 VHDL 或 Verilog 编写。这些技术可能有助于提高硬件工程师的编程效率,但它们并没有形成一种有效将真实软件转换为硬件电路(或其他类型的异构计算元件的代码)的方法的基础。
正如一些炼金术士最终为他们的工艺发现了足够的科学和理论基础,然后将自己重新命名为社会可接受的化学家一样,有迹象表明,在真正的高级综合领域正在发生类似的转变。两个非常令人鼓舞的项目认真地处理了将真实程序转换为电路的任务,分别是 IBM 的 Liquid Metal 项目,该项目基于 Lime 语言,该语言使用特殊的并发构造扩展了 Java3,以及剑桥大学 David Greaves 博士和剑桥微软研究院的 Kiwi 项目(该项目使用未修改的标准 .NET 编程语言,并依靠多线程程序来描述重要的并行执行经济性)6。
多核处理器和 GPU 架构开始彼此靠近。英特尔的 Sandy Bridge 处理器具有 AVX(高级矢量扩展指令集),它提供对 256 位寄存器的数据并行操作。AMD 的 Fusion 计划承诺在同一芯片上实现 CPU 和 GPU 核心之间更紧密的集成。已经有一个概念验证的单封装芯片,它结合了英特尔凌动处理器和 Altera FPGA。这可能是将类似 FPGA 的逻辑放在与处理器核心相同的芯片上的垫脚石。向异构世界的转变看起来是不可避免的。
尽管本文的重点一直是异构处理,但重要的是要注意,当前不断发展的异构系统由许多其他类型的异构元件组成(例如,存储、内存和网络)。不同类型的存储(例如,物理存储与固态存储)、内存(例如,处理具有不同访问经济性、延迟和可靠性特征的不同类型的内存)和网络(例如,光互连与铜缆以及差异巨大的协议)的管理对现代异构系统的系统软件和应用软件的设计提出了严峻的挑战。
在使用形状分析和区域类型的最新进展将使用指针操作堆数据结构的 C 程序转换为电路方面也取得了进展。高级综合领域的传统观点会让人相信这种转换是不可能的,但是今天您可以象征性地推断出关于 C 程序堆中发生的事情的惊人数量的信息,并且可以以更高的保真度确定任何给定指令可能触及的堆的哪些部分(与传统的指针分析相比)。
程序分析理论的这些进步为我们提供了将程序转换为电路(或 GPU 代码)的强大工具。这些技术允许硬件和软件之间界限的模糊,因为它们允许将以软件形式表示的计算(使用指针在堆上工作)重新表示为数组上的计算(当可以自动计算某些边界时),然后将代码重新映射到 GPU 或 FPGA。这种转换算法以保留其含义但重构它以在不同的数据表示上工作(更适合不同的执行环境)的能力,是使异构系统的可重定向编程成为可能的关键武器。
Luca Cardelli5 和 Masami Hagiya7 等研究人员正在设计使用 DNA 进行编程的技术,从而推动了使用 DNA 进行计算的可能性边界。此类研究可能会阐明如何构建不仅可以自我修复还可以自我组装的系统。尽管主流程序员不太可能很快使用 DNA 进行编程,但这些项目提醒我们,世界上有很多事物都具有计算能力。我们面临着一个令人兴奋的挑战,即研究如何对它们进行编程。
到目前为止,编程主要集中在哄骗 CPU 来实现我们的算法。这涉及对底层执行架构的经济性以及特别是内存系统架构的重大假设。为了满足我们对性能改进或降低能耗的要求,我们将越来越需要对与常规 CPU 架构截然不同的计算引擎进行编程。
将相同的计算映射到几个不同的计算元件通常涉及重写算法,以在每个架构上实现高效执行。与为 CPU 开发的原始算法相比,这通常涉及使用不同的编程语言和非常不同的执行模型。
这是一个昂贵的操作,尽管在许多情况下这是必要的,但有可能识别出一类受约束的问题,这些问题共享一些关键的架构假设。然后,可以利用这些知识来允许从一个描述到多个目标(例如 CPU 矢量指令、GPU 和 FPGA)的自动编译。
Accelerator 系统是这种方法的一个示例,它为模板式计算提供了一种嵌入式领域特定语言,可以使用 C、C++ 或任何支持 C 调用接口的语言(例如 C#、F# 或 Haskell)编写。在 Accelerator 的情况下,约束是使用仅允许整个数组操作(没有任意数组索引)的数据并行数组,以及提供显式内存转换操作(例如移位、旋转、步长)。这避免了在特定内存模型中进行烘焙,并允许将 Accelerator 数据并行计算有效地映射到非常不同的执行目标。
随着异构处理元件数量的增长,我们将需要开发一系列这样的嵌入式领域特定语言,每种语言都捕获特定领域(例如模板计算、XML 解析、正则表达式匹配)的计算要求的本质。对于每种嵌入式领域特定语言,我们都可以实现一种机制,用于将描述编译到特定的执行架构上。
通过结合在主流编程语言中通过库调用使用的嵌入式领域特定语言,我们可以朝着开发使异构系统编程变得易于处理的机制迈出重要一步,同时避免重新实现的成本或开发和采用新语言的成本。
问
1. Abadi, M., et al. 2011. 事务内存和自动互斥的语义。《 编程语言和系统汇刊 (TOPLAS)》33(1)。
2. Adve, S. V., Boehm, H-J. 2010. 内存模型:重新思考并行语言和硬件的理由。《 通讯》53(8)。
3. Auerbach, J., et al. 2010. Lime:一种与 Java 兼容且可合成的异构架构语言。 面向对象编程系统语言和应用国际会议 (OOPSLA 10) 会议记录。
4. Borkar, S., Chien, A. A. 2011. 微处理器的未来。《 通讯》54(5)。
5. Cardelli, L. 2009. DNA 计算的链代数。《自然计算》10(1): 407。
6. Greaves, D., Singh, S. 2010. 使用并发 C# 程序设计特定应用的电路。第八届 /IEEE 代码协同设计形式化方法和模型国际会议。
7. Hagiya, M. 1998. 面向自主分子计算机。第三届年度遗传编程会议会议记录。
8. Lesniak, M. 2010. PASTHA - Haskell 中的并行模板计算。第五届 SIGPLAN 多核编程声明性方面研讨会会议记录。
9. Madhavapeddy, A., Singh, S. 2011. 云的可重构数据处理。MSDN 博客; http://blogs.msdn.com/b/satnam_singh/archive/2011/01/18/reconfigurable-data-processing-for-clouds.aspx。
10. Nvidia Corporation. 2007. Nvidia CUDA(计算统一设备架构); http://developer.nvidia.com/cuda。
11. Owens, J. D., et al. 2008. GPU 计算。《IEEE 会刊》96(5)。
12. Shavit, N. 2011. 多核时代的数据结构。《 通讯》54(3)。
13. Tarditi, D., Puri, S., Oglesby, J. 2006. Accelerator:使用数据并行性对 GPU 进行通用用途编程。编程语言和操作系统架构支持。
14. Trancoso, P., Othonos, D., Artemiou, A. 2009. 使用 Cell/BE 和 GPU 对决策支持查询进行数据并行加速。2009 年 计算前沿国际会议会议记录。
15. Xu, L., Wan, J. W. 2008. 使用 Rapidmind 多核开发平台进行基于实时强度的刚性 2D-3D 医学图像配准。第 30 届 IEEE 工程医学与生物学学会年度国际会议会议记录。
喜欢它,讨厌它? 请告诉我们
Satnam Singh ([email protected]) 是英国剑桥微软研究院实验室的研究员,他在那里研究用于低级系统的高级设计技术。他还担任伯明翰大学可重构计算主席。(http://research.microsoft.com/~satnams; http://www.cs.bham.ac.uk/~singhsu/ )
© 2011 1542-7730/11/0600 $10.00
最初发表于 Queue 第 9 卷,第 6 期—
在 数字图书馆 中评论本文
David Chisnall - 如何设计 ISA
在过去的十年中,我参与了多个项目,这些项目设计了用于各种处理器的 ISA(指令集架构)扩展或全新 ISA(您甚至可以在 RISC-V 规范的致谢中找到我的名字,可以追溯到第一个公开版本)。当我开始时,我对什么构成好的 ISA 知之甚少,而且据我所知,这在任何地方都没有正式教授。
Gabriel Falcao, João Dinis Ferreira - 选择 PiM 还是不选择 PiM
随着人工智能成为数十亿边缘 IoT(物联网)设备的普及工具,数据移动瓶颈对这些系统的性能和自主性施加了严格的限制。PiM(内存内处理)正在兴起,成为一种缓解数据移动瓶颈的方法,同时满足依赖 CNN(卷积神经网络)的边缘成像应用的严格性能、能效和准确性要求。
Mohamed Zahran - 异构计算:大势所趋
在过去几年中,关于流行语异构计算的提及一直在增加,并且在未来几年将继续听到,因为异构计算是大势所趋。什么是异构计算,为什么它正在成为常态?我们如何从软件方面和硬件方面来处理它?本文提供了对其中一些问题的解答,并提出了对其他问题的不同观点。
David Chisnall - 没有所谓的通用处理器
计算机架构中存在将处理器和加速器归类为“通用”的日益增长的趋势。在今年国际计算机体系结构研讨会 (ISCA 2014) 上发表的论文中,45 篇中有 9 篇明确提到了通用处理器;另一篇还提到了通用 FPGA(现场可编程门阵列),还有一篇提到了通用 MIMD(多指令多数据)超级计算机,将定义扩展到了崩溃点。本文提出了一个论点,即没有真正的通用处理器,并且对这种设备的信念是有害的。