精华内容
下载资源
问答
  • 基于异构并行计算的大数据分析与挖掘 基于异构并行计算的大数据分析与挖掘
  • OPENCL异构并行计算 原理 机制与优化实践随书代码完整版
  • 本博文由 youngpan1101 出品,转载请注明出处。 文章链接:...作者: 宋洋鹏(youngpan1101) ... ps:该笔记是基于《OpenCL异构并行计算:原理、机制与优化实践, 刘文志等著》的学习笔记 目录...

    本博文由 youngpan1101 出品,转载请注明出处。 
    文章链接:https://blog.csdn.net/youngpan1101/article/details/101831696
    作者: 宋洋鹏(youngpan1101) 
    邮箱: yangpeng_song@163.com


    ps:该笔记是基于《OpenCL异构并行计算:原理、机制与优化实践, 刘文志等著》的学习笔记 

    目录

    异构并行计算的过去、现状和未来

    单核标量处理器 

    多核向量化

    OpenCL横空出世


    异构并行计算的过去、现状和未来

    • 异构:计算单元由不同的多种处理器组成。
    • 并行:要发挥异构硬件平台的全部性能必须要使用并行的编程方式。
    • 向量化:一种一条指令同时处理多个数据的方法,是一种数据并行技术。
      • SIMD(Single Instruction Multiple Data,单指令多数据)
        • SIMD操作:对两个长向量寄存器中的数据按元素进行操作,结果向量寄存器和源向量寄存器长度相同。
      • SIMT(Single Instruction Multiple Thread,单指令多线程)
    • 多核:在一块芯片上,集成多个处理器核心,这多个处理器核心共享或不共享缓存层次结构,多核处理器通常会共享主板上的物理内存。
    • 多路:将多个多核处理器互联在同一个主板上,各个多核处理器之间通常共享缓存或内存来交换数据。

    现代处理器提升性能的两种主要途径:多核 和 向量化,今天的绝大多数处理器都已经是多核向量化处理器。

    单核标量处理器 

    在2005年之前,单核标量处理器以近似摩尔定律(这里只简单地解释为“单核标量处理器性能每18个月提升一倍”)的方式提升性能,主要通过以下方式:

    • 提升处理器的时钟频率:时钟频率表示处理器1秒内可以运行多少个基本操作,这些基本操作需要一个时钟周期运行。提升频率即可以让处理器1秒内执行更多的基本操作,提升了处理器运行的所有指令的执行速度。
    • 提升指令级并行能力:没有减少某条指令的延迟,但它提升了处理器能够同时处理的指令数量,即将一条指令拆分成多个阶段来提供性能,如下图的五阶段流水线为例,若没有使用流水线执行,则原来需要5个周期才能完成2个操作,而使用流水线执行后,则每个周期能够完成2个操作。

     

    而在2005年之后,单核标量处理器的性能不能再以摩尔定律的速度提升,主要是因为:

    • 功耗限制了频率的继续提升:随之处理器频率的增加,功耗也会随之增加,对散热系统要求越来越高,若再增加频率,硬件组件可能不能正常工作,甚至烧毁。
    • 提升指令级并行遇到瓶颈:处理器设计通常会增加硬件流水线的级次,而现在该方法已达到其局限。

    多核向量化

    为了提供更高性能的处理器,生产商采用了以下两种方法:

    • 多核:通过复制处理器核心成倍增加了处理器的计算能力,能支持线程级并行处理,通过将线程映射到硬件核心上,以同时处理多个不同的请求,提高用户体验。
    • 向量化:通过增加寄存器的宽度和指令的宽度来同时处理多个数据,另外,许多算法和应用具有向量级并行(数据并行)能力,如一些算法需要对多个不同数据执行同一个操作。

    要发挥多核和向量化的计算能力,必须要编写向量化和多线程的代码,比如新出现的C编程语言扩展:CUDA和OpenCL,通过层次化的线程/编程模型使得一份代码同时支持向量化和多核。

    • OpenCL支持X86 CPU、GPU 和 ARM-GPU(Mali系列)

    OpenCL横空出世

    继2007年CUDA的推出,异构并行计算逐渐被认可,异构并行缓解了处理器发展面临的两个主要问题:性能和功耗。 

    在2008年,OpenCL横空出世,是异构平台并行编程的开放的工业标准,也是一个编程框架,包含以下两部分:

    • OpenCL C语言和主机端API;
    • 硬件架构的抽象

    OpenCL具有以下特点:

    • 高性能:OpenCL是底层API;
    • 适用性强:抽象了硬件的不同架构的共性,又兼顾了不同硬件的特点;
    • 开放:由开放组织开发、维护的标准;
    • 无替代选项:只有OpenCL得到了几乎所有相关主流硬件厂商的支持。

    正因以上OpenCL的众多特点,未来OpenCL必将无处不在。 

    展开全文
  • 如何成为一名异构并行计算工程师

    万次阅读 2017-12-15 10:18:16
    两个芯片计算力分别是10T和 20T,某人的异构并行计算能力为0.8,他拿到了计算力为10T的芯片,而异构并行计算能力为0.4的人拿到了计算力为20T的芯片,而实际上最终结果两人可能相差不大。异构并行计算能力强的人能够...

    随着深度学习(人工智能)的火热,异构并行计算越来越受到业界的重视。从开始谈深度学习必谈GPU,到谈深度学习必谈计算力。计算力不但和具体的硬件有关,且和能够发挥硬件能力的人所拥有的水平(即异构并行计算能力)高低有关。

    一个简单的比喻是:两个芯片计算力分别是10T和 20T,某人的异构并行计算能力为0.8,他拿到了计算力为10T的芯片,而异构并行计算能力为0.4的人拿到了计算力为20T的芯片,而实际上最终结果两人可能相差不大。异构并行计算能力强的人能够更好地发挥硬件的能力,而本文的目标就是告诉读者要变成一个异构并行计算能力强的工程师需要学习那些知识。

    异构并行计算是笔者提出的一个概念,它本质上是由异构计算和并行计算组合而来,一方面表示异构并行计算工程师需要同时掌握异构计算的知识,同时也需要掌握并行计算的知识;另一方面是为更好地发展和丰富异构计算和并行计算。通过异构并行计算进一步提升了知识的系统性和关联性,让每一个异构并行计算工程师都能够获得想要的工作,拿到值得的薪水。

    对于一个异构并行计算工程师的日常来说,他的工作涉及的方面很广,有硬件,有软件,有系统,有沟通;是一个对硬实力和软实力都有非常高要求的岗位。

    异构并行计算的难度是非常高的,而市场对这个职位的需求一直在提升,期待读者能够和我一起投身于异构并行计算的行列,为异构并行计算在中国的推广做出贡献。

    异构并行计算工程师技能树

    要想成为一个优秀的异构并行计算工程师需要掌握许多知识和技能,这些技能可以分为两个方面:

    1. 处理器体系,处理器如何执行具体的指令;
    2. 系统平台方面,这又可以分成多个细的主题,包括硬件的特点,软件编程相关的平台和基础设施。

    读者可以从图1具体了解到异构并行计算工程师需要掌握的技能和知识。

    图片描述

    图1 异构并行计算工程师技能树

    异构并行计算工程师成长详解

    每个人甚至每个技术领域都是在不停的成长,通常公司的岗位会区分为初级、中级、高级、主任等,这是按照贡献、能力和责任大小来分,并不适合用来表示技术。为了更好地帮助读者学习知识,本文从技能体系角度来分析,因此并不能对应到各个公司招聘的岗位需求上,也意味着读者不能简单的把本文的技能和各个公司的岗位级别对应。

    为了帮助读者更好地理解,本文会使用先硬件后软件的方式介绍。和异构并行工程师相关性最大的硬件知识即处理器特性,我们从这一点开始。

    现代处理器的特性

    从系统启动到终止,处理器一条接着一条地执行存储器中的指令,站在使用者的角度来看就好像是前一条指令执行完之后下一条指令才开始执行,是一个完完全全的串行过程。实际上,现代处理器利用了指令级并行技术,同一时刻存在着多条指令同时被执行,并且处理器执行指令的顺序无需和汇编代码给出的指令顺序完全一致,编译器和处理器只需要保证最终结果一致即可,这类处理器称为“乱序执行处理器”。而严格按照顺序一次执行一条指令,只有前一条执行完才开始执行后一条指令的处理器,称为“按序处理器”。而即使是在按序执行处理器上,编译器也可以对源代码进行类似的优化,以提高程序性能。对于一个特定的流水线来说,现代乱序执行处理器只保证指令执行阶段可以乱序,而其他阶段通常还是顺序的。目前主流的CPU和GPU,甚至DSP,无论是在服务器端,还是在移动端基本上都已经是乱序执行处理器了。

    今天大多数处理器都是哈佛架构的变体,其根本特征是在程序执行时把指令和数据分开存储,程序员通常可以忽略指令存储,实际上异构并行计算更关注的是:计算和数据访问。

    计算和访存

    以作者正在使用的处理器E5-2680v3来说,其主频为2.6GHz,支持FMA指令集,其单核单精度浮点计算能力为2.6*2*8*2=83.2 GFlops;而单通道内存的带宽大约为20GB/s。主流处理器的处理速度远快于内存读写速度,为了减小访问数据时的延迟,现代主流处理器主要采用了两种方式:

    • 利用程序访问数据的局部性特点:采用了一系列小而快的缓存保存正在访问和将要被访问的数据,如果数据会被多次访问且数据能够被缓存容纳,则能够以近似于内存的价格获得近似于缓存的速度;
    • 利用程序的并行性:在一个控制流由于高延迟的操作而阻塞时,执行另一个控制流,这样能够提高处理器核心的利用率,保证处理器核心一直在忙碌的状态。

    简单来说,前一种方法是将经常访问的数据保存在低延迟的缓存中,以减少访问数据时的延迟,通过更快为处理器提供数据而提高性能,主要是目前主流的CPU采用。而后一种方法则尽量保证运算单元一直在忙碌工作,通过提高硬件的利用率以提高程序的吞吐量,这种方法目前主要为主流的GPU所采用。这两种办法没有天然的壁垒,现代处理器(无论是CPU还是GPU)都采用了这两种方法,区别只是更偏重于使用哪一种方法。

    指令级并行

    现代处理器具有许多和代码性能优化相关的特点,本节主要介绍以下部分:

    • 指令级并行技术:主要有流水线、多发射、VLIW、乱序执行、分支预测、超标量等技术;
      向量化:主要有SIMT和SIMD技术;
    • 软件开发人员如果了解现代多核向量处理器的这些特性,就能写出性能效率超过一般开发人员的代码。

    多核

    多核是指一个CPU模块里包含多个核心,每个核心是一个独立的计算整体,能够执行线程。现代处理器都是多核处理器,并且为多核使用场景所优化。

    多核的每个核心里面具有独立的一级缓存,共享的或独立的二级缓存,有些机器还有独立或共享的三级/四级缓存,所有核心共享内存DRAM。通常第一级缓存是多核处理器的一个核心独享的,而最后一级缓存(Last Level Cache, LLC)是多核处理器的所有核心共享的,大多数多核处理器的中间各层也是独享的。如Intel Core i7处理器具有4~8个核,一些版本支持超线程,其中每个核心具有独立的一级数据缓存和指令缓存、统一的二级缓存,并且所有的核心共享统一的三级缓存。

    由于共享LLC,因此多线程或多进程程序在多核处理器上运行时,平均每个进程或线程占用的LLC缓存相比使用单线程时要小,这使得某些LLC或内存限制的应用的可扩展性看起来没那么好。

    由于多核处理器的每个核心都有独立的一级、有时还有独立的二级缓存,使用多线程/多进程程序时可利用这些每个核心独享的缓存,这是超线性加速(指在多核处理器上获得的性能收益超过核数)的原因之一。

    多路与NUMA

    硬件生产商还将多个多核芯片封装在一起,称之为多路,多路之间以一种介于共享和独享之间的方式访问内存。由于多路之间缺乏缓存,因此其通信代价通常不比DRAM低。一些多核也将内存控制器封装进多核之中,直接和内存相连,以提供更高的访存带宽。

    多路上还有两个和内存访问相关的概念:UMA(均匀内存访问)和NUMA(非均匀内存访问)。UMA是指多个核心访问内存中的任何一个位置的延迟是一样的,NUMA和UMA相对,核心访问离其近(指访问时要经过的中间节点数量少)的内存其延迟要小。如果程序的局部性很好,应当开启硬件的NUMA支持。

    硬件平台

    异构并行计算人员的能力最终需要通过运行在硬件上的程序来证明,这意味着异构并行计算编程人员对硬件的了解与其能力直接正相关。

    目前大家接触到处理器主要类型有:X86、ARM、GPU、FPGA等,它们的差别非常大。

    X86

    X86是Intel/AMD及相关厂商生产的一系列CPU处理器的统称,也是大家日常所见。X86广泛应用在桌面、服务器和云上。

    SSE是 X86 向量多核处理器支持的向量指令,具有16个长度为128位(16个字节)的向量寄存器,处理器能够同时操作向量寄存器中的16个字节,因此具有更高的带宽和计算性能。AVX将SSE的向量长度延长为256位(32字节),并支持浮点乘加。现在,Intel已将向量长度增加到512位。由于采用显式的SIMD编程模型,SSE/AVX的使用比较困难,范围比较有限,使用其编程是一件比较痛苦的事情。

    MIC是Intel的众核架构,它拥有大约60左右个X86核心,每个核心包括向量单元和标量单元。向量单元包括32个长度为512位(64字节)的向量寄存器,支持16个32位或8个64位数同时运算。目前的MIC的核为按序的,因此其性能优化方法和基于乱序执行的X86处理器核心有很大不同。

    为了减小使用SIMD指令的复杂度,Intel寄希望于其编译器的优化能力,实际上Intel的编译器向量化能力非常不错,但是通常手工编写的向量代码性能会更好。在MIC上编程时,软件开发人员的工作部分由显式使用向量指令转化为改写C代码和增加编译制导语句以让编译器产生更好的向量指令。

    另外,现代64位X86 CPU还利用SSE/AVX指令执行标量浮点运算。

    ARM

    目前高端的智能手机、平板使用多个ARM核心和多个GPU核心。在人工智能时代,运行在移动设备上的应用对计算性能需求越来越大,而由于电池容量和功耗的原因,移动端不可能使用桌面或服务器高性能处理器,因此其对性能优化具有很高需求。

    目前市场上的高性能ARM处理器主要是32位的A7/A9/A15,已经64位的A53/A57/A72。ARM A15 MP是一个多核向量处理器,它具有4个核心,每个核心具有64KB一级缓存,4个核心最大可共享2MB的二级缓存。ARM 32支持的向量指令集称为NEON。NEON具有16个长度为128位的向量寄存器(这些寄存器以q开头,也可表示为32个64位寄存器,以d开头),可同时操作向量寄存器的16个字节,因此使用向量指令可获得更高的性能和带宽。ARM A72 MP是一个多核向量处理器,其最多具有4个核心,每个核心独享32KB的一级数据缓存,四个核心最高可共享4MB统一的二级缓存。ARM 64支持的向量指令集称为asimd,指令功能基本上兼容neon,但是寄存器和入栈规则具有明显的不同,这意味着用neon写的汇编代码不能兼容asimd。

    GPU

    GPGPU是一种利用处理图形任务的GPU来完成原本由CPU处理(与图形处理无关的)的通用计算任务。由于现代GPU强大的并行处理能力和可编程流水线,令其可以处理非图形数据。特别在面对单指令流多数据流(SIMD),且数据处理的运算量远大于数据调度和传输的需要时,GPGPU在性能上大大超越了传统的CPU应用程序。

    GPU是为了渲染大量像素而设计的,并不关心某个像素的处理时间,而关注单位时间内能够处理的像素数量,因此带宽比延迟更重要。考虑到渲染的大量像素之间通常并不相关,因此GPU将大量的晶体管用于并行计算,故在同样数目的晶体管上,具有比CPU更高的计算能力。

    CPU和GPU的硬件架构设计思路有很多不同,因此其编程方法很不相同,很多使用CUDA的开发人员有机会重新回顾学习汇编语言的痛苦经历。GPU的编程能力还不够强,因此必须要对GPU特点有详细了解,知道哪些能做,哪些不能做,才不会出现项目开发途中发觉有一个功能无法实现或实现后性能很差而导致项目中止的情况。

    由于GPU将更大比例的晶体管用于计算,相对来说用于缓存的比例就比CPU小,因此通常局部性满足CPU要求而不满足GPU要求的应用不适合GPU。由于GPU通过大量线程的并行来隐藏访存延迟,一些数据局部性非常差的应用反而能够在GPU上获得很好的收益。另外一些计算访存比低的应用在GPU上很难获得非常高的性能收益,但是这并不意味着在GPU实现会比在CPU上实现差。CPU+GPU异构计算需要在GPU和CPU之间传输数据,而这个带宽比内存的访问带宽还要小,因此那种需要在GPU和CPU之间进行大量、频繁数据交互的解决方案可能不适合在GPU上实现。

    FPGA

    FPGA是现场可编程门阵列的缩写,随着人工智能的流行,FPGA越来越得到产业界和学术界的重视。FPGA的主要特点在于其可被用户或设计者重新进行配置,FPGA的配置可以通过硬件描述语言进行,常见的硬件描述语言有VHDL和verilog。

    使用VHDL和Verilog编程被人诟病的一点在于其编程速度。随着FPGA的流行,其编程速度越来越得到重视,各个厂商都推出了各自的OpenCL编程环境,虽然OpenCL降低了编程难度,但是其灵活性和性能也受到很大的限制。

    传统上,FPGA用于通信,现在FPGA也用于计算和做硬件电路设计验证。目前主流的两家FPGA厂商是Altera和Xilinx,Intel在2014年收购了Altera,估计在2018年,Intel X86+FPGA的异构产品会出现在市场。

    编程环境

    本节将详细介绍目前主流的并行编程环境,既包括常见的指令级并行编程技术,也包括线程级并行编程技术和进程级技术。

    Intel AVX/AVX512 Intrinsic

    SSE/AVX是Intel推出的用以挖掘SIMD能力的汇编指令。由于汇编编程太难,后来Intel又给出了其内置函数版本(intrinsic)。

    SSE/AVX指令支持数据并行,一个指令可以同时对多个数据进行操作,同时操作的数据个数由向量寄存器的长度和数据类型共同决定。如SSE4向量寄存器(xmm)长度为128位,即16个字节。如果操作float或int型数据,可同时操作4个,如果操作char型数据,可同时操作16个,而AVX向量寄存器(ymm)长度为256位,即32字节。

    虽然SSE4/AVX指令向量寄存器的长度为128/256 位,但是同样支持更小长度的向量操作。在64位程序下,SSE4/AVX 向量寄存器的个数是16个。

    SSE指令要求对齐,主要是为了减少内存或缓存操作的次数。SSE4指令要求16字节对齐,而AVX指令要求32字节对齐。SSE4及以前的SSE指令不支持不对齐的读写操作,为了简化编程和扩大应用范围,AVX指令支持非对齐的读写。

    ARM NEON Intrinsic

    NEON是ARM处理器上的SIMD指令集扩展,由于ARM在移动端得到广泛应用,目前NEON的使用也越来越普遍。

    NEON支持数据并行,一个指令可同时对多个数据进行操作,同时操作的数据个数由向量寄存器的长度和数据类型共同决定。

    ARMv7具有16个128位的向量寄存器,命名为q0~q15,这16个寄存器又可以分成32个64位寄存器,命名为d0~d31。其中qn和d2n、d2n+1是一样的,故使用汇编写代码时要注意避免寄存器覆盖。

    OpenMP

    OpenMP是Open Multi-Processing的简称,是一个基于共享存储器的并行环境。OpenMP支持C/C++/Fortran绑定,也被实现为库。目前常用的GCC、ICC和Visual Studio都支持OpenMP。

    OpenMP API包括以下几个部分:一套编译器伪指令,一套运行时函数,一些环境变量。OpenMP已经被大多数计算机硬件和软件厂商所接受,成为事实上的标准。

    OpenMP提供了对并行算法的高层的抽象描述,程序员通过在源代码中插入各种pragma伪指令来指明自己的意图,编译器据此可以自动将程序并行化,并在必要之处加入同步互斥等通信。当选择告诉编译器忽略这些pragma或者编译器不支持OpenMP时,程序又可退化为串行程序,代码仍然可以正常运作,只是不能利用多线程来加速程序执行。OpenMP提供的这种对于并行描述的高层抽象降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。对基于数据并行的多线程程序设计,OpenMP是一个很好的选择。同时,使用OpenMP也提供了更强的灵活性,可以适应不同的并行系统配置。线程粒度和负载均衡等是传统并行程序设计中的难题,但在OpenMP中,OpenMP库从程序员手中接管了这两方面的部分工作。

    OpenMP的设计目标为:标准、简洁实用、使用方便、可移植。作为高层抽象,OpenMP并不适合需要复杂的线程间同步、互斥及对线程做精密控制的场合。OpenMP的另一个缺点是不能很好地在非共享内存系统(如计算机集群)上使用,在这样的系统上,MPI更适合。

    MPI

    MPI(Message Passing Interface,消息传递接口)是一种消息传递编程环境。消息传递指用户必须通过显式地发送和接收消息来实现处理器间的数据交换。MPI定义了一组通信函数,以将数据从一个MPI进程发送到另一个MPI进程。在消息传递并行编程中,每个控制流均有自己独立的地址空间,不同的控制流之间不能直接访问彼此的地址空间,必须通过显式的消息传递来实现。这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采用的主要编程方式。实践表明MPI的扩展性非常好,无论是在几个节点的小集群上,还是在拥有成千上万节点的大集群上,都能够很好地应用。

    由于消息传递程序设计要求用户很好地分解问题,组织不同控制流间的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法。MPI是基于进程的并行环境。进程拥有独立的虚拟地址空间和处理器调度,并且执行相互独立。MPI设计为支持通过网络连接的机群系统,且通过消息传递来实现通信,消息传递是MPI的最基本特色。

    MPI是一种标准或规范的代表,而非特指某一个对它的具体实现,MPI成为分布式存储编程模型的代表和事实上的标准。迄今为止,所有的并行计算机制造商都提供对MPI的支持,可以在网上免费得到MPI在不同并行计算机上的实现,一个正确的MPI程序可以不加修改地在所有的并行机上运行。

    MPI只规定了标准并没有给出实现,目前主要的实现有OpenMPI、Mvapich和MPICH,MPICH相对比较稳定,而OpenMPI性能较好,Mvapich则主要是为了Infiniband 而设计。

    MPI主要用于分布式存储的并行机,包括所有主流并行计算机。但是MPI也可以用于共享存储的并行机,如多核微处理器。编程实践证明MPI的可扩展性非常好,其应用范围从几个机器的小集群到工业应用的上万节点的工业级集群。MPI已在Windows上、所有主要的UNIX/Linux工作站上和所有主流的并行机上得到实现。使用MPI进行消息传递的C或Fortran并行程序可不加改变地运行在使用这些操作系统的工作站,以及各种并行机上。

    OpenCL

    OpenCL(Open Computing Language,开放计算语言),先由Apple设计,后来交由Khronos Group维护,是异构平台并行编程的开放的标准,也是一个编程框架。Khronos Group是一个非盈利性技术组织,维护着多个开放的工业标准,并且得到了工业界的广泛支持。OpenCL的设计借鉴了CUDA的成功经验,并尽可能的支持多核CPU、GPU或其他加速器。OpenCL不但支持数据并行,还支持任务并行。同时OpenCL内建了多GPU并行的支持。这使得OpenCL的应用范围比CUDA广,但是目前OpenCL的API参数比较多(因为不支持函数重载),因此函数相对难以熟记。

    OpenCL覆盖的领域不但包括GPU,还包括其他的多种处理器芯片。到现在为止,支持OpenCL的硬件主要局限在CPU、GPU和FPGA上,目前提供OpenCL开发环境的主要有NVIDIA、AMD、ARM、Qualcomm、Altera和Intel,其中NVIDIA和AMD都提供了基于自家GPU的OpenCL实现,而AMD和Intel提供了基于各自CPU的OpenCL实现。目前它们的实现都不约而同地不支持自家产品以外的产品。由于硬件的不同,为了写出性能优异的代码,可能会对可移植性造成影响。

    OpenCL包含两个部分:一是语言和API,二是架构。为了C程序员能够方便、简单地学习OpenCL,OpenCL只是给C99进行了非常小的扩展,以提供控制并行计算设备的API以及一些声明计算内核的能力。软件开发人员可以利用OpenCL开发并行程序,并且可获得比较好的在多种设备上运行的可移植性。

    OpenCL的目标是一次编写,能够在各种硬件条件下编译的异构程序。由于各个平台的软硬件环境不同,高性能和平台间兼容性会产生矛盾。而OpenCL允许各平台使用自己硬件的特性,这又增大了这一矛盾。但是如果不允许各平台使用自己的特性,却会阻碍硬件的改进。

    CUDA

    CUDA认为系统上可以用于计算的硬件包含两个部分:一个是CPU(称为主机),一个是GPU(称为设备),CPU控制/指挥GPU工作,GPU只是CPU的协处理器。目前CUDA只支持NVIDIA的GPU,而CPU由主机端编程环境负责。

    CUDA是一种架构,也是一种语言。作为一种架构,它包括硬件的体系结构(G80、GT200、Fermi、Kepler)、硬件的CUDA计算能力及CUDA程序是如何映射到GPU上执行;作为一种语言,CUDA提供了能够利用GPU计算能力的方方面面的功能。CUDA的架构包括其编程模型、存储器模型和执行模型。CUDA C语言主要说明了如何定义计算内核(kernel)。CUDA架构在硬件结构、编程方式与CPU体系有极大不同,关于CUDA的具体细节读者可参考CUDA相关的书籍。

    CUDA以C/C++语法为基础而设计,因此对熟悉C系列语言的程序员来说,CUDA的语法比较容易掌握。另外CUDA只对ANSI C进行了最小的扩展,以实现其关键特性:线程按照两个层次进行组织、共享存储器(shared memory)和栅栏(barrier)同步。

    目前CUDA提供了两种API以满足不同人群的需要:运行时API和驱动API。运行时API基于驱动API构建,应用也可以使用驱动API。驱动API通过展示低层的概念提供了额外的控制。使用运行时API时,初始化、上下文和模块管理都是隐式的,因此代码更简明。一般一个应用只需要使用运行时API或者驱动API中的一种,但是可以同时混合使用这两种。笔者建议读者优先使用运行时API。

    编程模式

    和串行编程类似,并行编程也表现出模式的特征,并行编程模式是对某一类相似并行算法的解决方案的抽象。

    和串行编程类似,并行编程对于不同应用场景也有不同的解决方法。由于并行的特殊性,串行的解决方法不能直接移植到并行环境上,因此需要重新思考、设计解决方法。并行编程模式大多数以数据和任务(过程化的操作)为中心来命名,也有一些是以编程方法来命名。

    经过几十年的发展,人们已经总结出一系列有效的并行模式,这些模型的适用场景各不相同。本节将简要说明一些常用并行模式的特点、适用的场景和情况,具体的描述和实现则在后文详细描述。

    需要说明的是:从不同的角度看,一个并行应用可能属于多个不同的并行模式,本质原因在于这些并行模式中存在重叠的地方。由于模式并非正交,因此适用于一种模式的办法可能也适用于另一种模式,读者需要举一反三。

    任务并行模式

    任务并行是指每个控制流计算一件事或者计算多个并行任务的一个子任务,通常其粒度比较大且通信很少或没有。

    由于和人类的思维方式比较类似,任务并行比较受欢迎,且又易于在原有的串行代码的基础上实现。

    数据并行模式

    数据并行是指一条指令同时作用在多个数据上,那么可以将一个或多个数据分配给一个控制流计算,这样多个控制流就可以并行,这要求待处理的数据具有平等的特性,即几乎没有需要特殊处理的数据。如果对每个数据或每个小数据集的处理时间基本相同,那么均匀分割数据即可;如果处理时间不同,就要考虑负载均衡问题。通常的做法是尽量使数据集的数目远大于控制流数目,动态调度以基本达到负载均衡。

    数据并行对控制的要求比较少,因此现代GPU利用这一特性,大量减少控制单元的比例,而将空出来的单元用于计算,这样就能在同样数量的晶体管上提供更多的原生计算能力。

    基于进程的、基于线程的环境,甚至指令级并行环境都可以很好地应用在数据并行上。必要时可同时使用这三种编程环境,在进程中分配线程,在线程中使用指令级并行处理多个数据,这称为混合计算。

    异构并行计算领域现状

    在2005年之前,处理器通常提升频率来提升计算性能,由于性能是可预测的,因此在硬件生产商、研究人员和软件开发人员之间形成了一个良性循环。由于功耗的限制,处理器频率不能接着提升,硬件生产商转而使用向量化或多核技术。而以GPU计算为代表的异构并行计算的兴起,加上人工智能的加持,异构并行计算从学术界走向工业界,获得了大众的认可。今天几乎所有主流的处理器硬件生产商都已经在支持OpenCL,未来异构并行计算必将无处不在。今天无论上技术上还是市场上,它都获得了长足的发展,笔者可以预计在未来的十年,异构并行计算必将进一步深入发展,并且在更多的行业产生价值。

    技术进展

    由于工艺制程的影响,芯片的集成度提升会越来越难,现在14nm已经量产,未来7nm也将很快。随着制程技术到达极限,某些厂商通过制程领先一代的优势会消失,软件公司会进一步重视异构并行计算人才的价值。而一些硬件厂商会进化成系统厂商,不再只是提供单纯的硬件,进而会硬件和系统软件一起提供,通过把软件的成本转嫁到硬件上来获得利润。

    随着异构并行计算影响力的提升,各个厂商和组织开发了一系列的技术,如WebCL、OpenVX、Vulkan等。这些技术进一步丰富和扩张了异构并行计算的领域,更促进了异构并行计算。今天基本上每家硬件和系统软件公司都或多或少的涉及到了异构并行计算。

    市场需求

    随着人工智能的兴起,市场对异构并行计算领域人员的需求已经从传统的科学计算、图像处理转到互联网和新兴企业,目前人员缺口已经很大了,从51job和智联招聘上能够查到许多招聘信息。

    由于目前还在行业的早期,异构并行计算开发人员的能力和老板期望和支出之间存在明显的认知差距,再加上异构并行计算开发人员的工作成果往往需要和产品间接反应,故在多个层面上存在博弈。对于异构并行计算领域的人员来说,这个博弈有点不公平,因为职业特点要求异构并行计算领域的从业人员要比算法设计人员更了解算法实现细节、要比算法实现人员更了解算法的应用场景,再加上编程上的难度和需要付出更多的时间。但是由于行业刚形成不久,老板们并没有意识到这一点,他们还只是把异构并行计算从业人员当成普通的开发者,矛盾就产生了。

    随着人工智能的兴起,市场对异构并行计算从业人员的认知逐渐变得理性。越来越多的企业认识到:异构并行计算是人工智能企业最核心的竞争力之一。可以预见在不远的将来,异构并行计算工程师会越来越吃香。

    作者简介:
    刘文志,商汤科技高性能计算部门负责人,硕士毕业于中国科学院研究生院。曾于2011年至2014年间于英伟达担任并行计算工程师。后就职百度深度学习研究院高级研发工程师,负责异构计算组日常工作。
    责编:何永灿(heyc@csdn.net
    本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅《程序员》


    订阅程序员(含iOS、Android及印刷版)请访问 http://dingyue.programmer.com.cn
    这里写图片描述

    订阅咨询:

    • 在线咨询(QQ):2251809102
    • 电话咨询:010-64351436
    • 更多消息,欢迎关注“程序员编辑部
    展开全文
  • OpenCL异构并行计算第二版的随书源码,学习书时必备的材料
  • OpenCL——异构并行计算简介

    千次阅读 2019-10-15 11:13:58
    异构并行计算 异构并行计算包括两个方面的内容:异构和并行。异构是指:计算单元由不同的多种处理器组合,如X86 CPU+GPU、ARM CPU+GPU、X86 CPU+FPGA、ARM CPU+DSP等。并行是指:要发挥异构硬件平台的全部性能必须要...

    异构并行计算

    异构并行计算包括两个方面的内容:异构和并行。异构是指:计算单元由不同的多种处理器组合,如X86 CPU+GPU、ARM CPU+GPU、X86 CPU+FPGA、ARM CPU+DSP等。并行是指:要发挥异构硬件平台的全部性能必须要使用并行的编程方式。通常包含两个层次的内容:

    • 多个不同架构的处理器同时计算,要发挥异构系统中所有处理器的性能,可通过并行程序使得每个处理都参与运算,避免处理器的闲置。相比于只让某一种类型的处理器参与工作,这种方式提高了性能的上限。
    • 每个处理都是多核向量处理器。这要求使用并行编程以发挥每个每个处理器的计算能力。通常每个处理器包括多个核心,每个核心包括一个或多个长向量。

    单核标量处理器的困境

    在2005年之前,大多数处理器都是单核的,一些处理器已经开始支持向量化(如X86处理器支持的MMX多媒体扩展)和SSE(流式SIMD扩展)指令集。但是绝大多数应用程序并没有进行向量化。

    在2005年之后,单标量处理器的性能基本上达到了顶峰,很难进一步大幅度提升性能。

    单核标量处理器是如何提高性能

    主要通过以下的方式提升性能:

    • 提升处理器的时钟频率:处理器的时针频率表示处理器1秒内可以运行多个基本操作,这些基本操作需要一个时钟周期运行。在某个固定的处理器上,一些复杂的操作可能需要多个时钟才能执行完成,或由多个基本操作组成。一条指令从开始到执行完成所需要的时针周期数,称为指令的延迟。
    • 提升指令级并行能力:单核标量处理上具有很多不同的部件,每个部件执行不同的指令。如果能够让多条做不同动作的指令同时操作,那么多个部件就可以同时进行指令操作,这称为指令级并行。

    在这里插入图片描述

    流水线示例

    五阶段流水线将指令的执行过程划分为:取指令(Instruction Fetch,IF)、指令解码(Instrcution Decode,ID)、执行(Execution,EX)、访存(Memory Access,MEM)和写回(Write Back,WB)。假设处理器支持两条流水线同时操作。每个周期内,都会有两条指令执行完成,两条新指令加入执行。执行的步骤如上图所示。从整体来看,若没有使用流水线执行,则原来需要5个周期才能完成2个在操作,而使用流水线执行后,则每个周期能够完成2个操作。

    单核处理器性能到达瓶颈

    单核标量处理器的性能不能再以摩尔处理器的速速提升,主要的原因:

    • 功耗限制了频率的继续提升:从物理定理来看,随着处理器工艺制程的推进,处理器的最大功耗(主要是漏电功耗)越来越大,这意味着随着处理器频率的增加,处理器功耗会大幅度增加。处理器功耗增加,则处理器工作时越来越热,对散热系统要求越来越高。
    • 提升指令级并行遇到瓶颈:指令级并行能够让处理器的多个不同的流水线组件同时工作。指令级并行能够增大处理器组件的利用率,极大地提高处理器的性能。处理器设计师在硬件层次提供了重排缓冲区(Reorder Buffer,ROB)、发射队列(issue queue)和寄存器重命名单元(register renameing)等来挖掘指令执行时不相关性。

    在提升指令级并行遇到瓶颈后,硬件设计师通过硬件寄存器的长度提升性能。例如原来的寄存器长度为32位,现在提供到128位,这意味着原来的一个寄存器能够存放一个单进度浮点数据,而现在一个寄存器能够保存4个这样的数据。

    多核并行计算和向量化的出现

    今天的绝大多数处理器,如X86多核CPU、ARM多核CPU、GPU以及DSP等,都已经是多核向量处理器。多核和向量化的出现满足了应用对计算机能力的需求。

    多核的原因

    多核通过复制处理器核心成倍了处理器的计算能力,多核的的出现除了消耗的原因外,还有很多其他原因。

    随着数据量越来越大,处理大量数据需要的计算性能的需求也越来远大,但是处理器商没有办法提供性能更好的处理器、

    向量化的原因

    如果代码使用128位向量化处理单精度数据,那么每次可以同时处理4个数据。

    利用多核和向量化的能力

    要同时发挥向量化和多核的计算能力,必须要编写向量化和多线程代码。主要有两种:

    • 分别编写向量化代码和线程级代码
    • 统一编写向量化代码和多线程代码

    常见的编写语言,如C11/C+11和Java等语言本身已经内置了线程级并行能力,而其他的语言则需要使用语言自身到机制。要发挥多核向量处理器的向量计算能力,则需要使用能够硬件生产商提供了内联汇编(也称为内置函数)。例如Intel/AMD为其X86提供了SSE/AVX指令集的C语言内置函数,ARM也为其CPU处理器提供了NEON指令集的C语言内置函数。

    一些新的C编程语言扩展,如CUDA和OpenCL,通过层次化的线程/编程模型使得一份代码同时支持向量化和多核。

    OpenCL不但支持GPU,还支持X86 CPU和ARM,一些移动处理器的GPU也开始支持OpenCL、目前一些FPGA和DSP的厂商也提供了OpenCL的支持。

    多核和向量化的难点

    1. 无论是向量化还是多核并行化,这两者意味着需要并行haul代码,但是根据Amdahl定理程序中串行代码的比例限制了并行化代码能够取得的最好的效果。
    2. 现在的多核向量处理器(尤其是X86)为了减少获取数据的延迟,使用了大量的缓存来保存多次重复访问的数。在很多的情况下,缓存能够增加程序的现实计算能力。但是缓存并不贡献硬件的原生计算能力(从某种程度上说,缓存是对处理器资源的一种浪费)。
    3. 有些代码不能使用多核并行化或向量化。一些算法的运算具有内在的串行特点,因为必须串行化。
    4. 在很多情况下,要发挥向量化和多核的计算能力,可能需要多份代码,这增加了代码维护代价。要编写向量化代码或多核并行代码,需要分析代码中数据和操作的依赖关系,处理任务和数据划分,并将其高效地映射到向量化和多核硬件上。
    5. 在一些应用严格的应该场景下,限制了其不能允许向量化和多线程导致的计算结果出现了偏差。

    异构并行计算的崛起

    从2007年NVIDIA退出了CUDA计算环境开始,异构并行计算逐渐得到了大众的认同。异构并行计算包含两个子概念:异构和并行

    1. 异构:异构并行计算需要同时处理多个不同架构的计算平台问题,如目前主流的异构并行计算平台:X86+GPU、X86+FPGA、以及目前正在研发中的ARM/Power+GPU。
    2. 并行:异构计算主要采用并行的编程方式,无论是X86处理器,还是ARM和GPU处理器以及DSP,这里所有的处理器都是多核向量处理器,要发挥多种处理器混合平台的性能必须采用并行的编程方式。

    异构并行计算出现的主要的两种问题:

    1. 性能问题
    2. 功耗问题

    GPGPU的理念

    在NVIDIA推出其CUDA计算环境之前,很多科学家就已经意识到如果能力利用GPU提供的强大计算能力计算一些通用运算,就能够获得很高的计算速度。在哪个时代,要使用GPU计算,则必须要将算法映射成图形的渲染过程,那时用来进行图形编程的主要应用编程接管口是OpenGL,即使用OpenGL将计算过程映射成为图形渲染过程,进而达成计算的目的,这称之为GPGPU。

    CUDA的崛起

    在2007年,NVIDIA退出了GTX8800 GPU,与之前为图形渲染的每个阶段独立设计流水线不同,GTX8800采用统一的渲染架构。同一处理器会处理图形渲染的全部流水线,这不仅提升了硬件的利用率,获得图形渲染的高性能。

    NVIDIA称CUDA是计算统一设备架构(Computing Unified Device Architecture)缩写,但是今天CUDA的范围已经远远超出了NVIDIA当初的定义,CUDA已经成为NVIDIA通用GPU并行计算编程平台和编程模型的抽象,一个符号,一个生态系统。

    CUDA平台提供了CUDA C语言扩展,相比普通C语言,CUDA C增加了使用NVIDIA CPU进行通用计算必不可少的一些语言扩展,其他功能功能都通过函数库提供。CUDA C以C/C++语言为基础而设计,因此对熟悉的C系统语言的程序员来说,CUDA的语法比较容易掌握。另外CUDA只对 ANSI C 进行了最小的扩展,以实现其关键特性::形成按照两个层次进行组织、共享存储器(shared memory)和栅栏(barrier)同步。

    由于CUDA由NIVDIA一家设计,并未被Intel和AMD接受,因此目前使用的CUDA编写的程序只支持NVIDIA GPU,而OpenGL的出现解决了这一问题。

    OpenCL的发展

    OpenCL全称为Open Computing Language(开放计算语言),先由Apple设计,后来交由Khronos Group维护,是异构平台并行编程的开发的标准,也是编程架构。OpenCL的设计借鉴了CUDA的成功经验,并尽可能地支持多核CPU,GPU或其他加速器,OpenCL不断支持数据并行,还支持任务并行。同时OpenCL内建了多GPU并行的支持。OpenCL API 基于纯C语言进行编写,所以OpenCL API的函数名比较长,参数也比较多(不支持函数重载),因此函数名相对难以记忆。

    OpenCL涵盖的领域不但包括GPU,还包括其他的多种处理器芯片。到现在为止,支持OpenCL的硬件主要局限在CPU、GPU、DSP和FPGA上,目前在桌面端和服务器端提供OpenCL开发环境的主要有Apple,NVIDIA、AMD、ARM和Intel,其中Apple提供了一个独立的OpenCL开发环境并与自家的OS X系统完整地融合在一起,NVIDIA和AMD都提供了基于自家的GPU的OpenCL在Windows和OpenCL实现。

    OpenCL包含两个部分,一是OpenCL C语言(OpenCL 2.1将开始使用OpenCL C++作为内核编程语言)和主机端API。二是硬件架构的抽象,OpenCL只是给C11进行了非常小的扩展,以提供控制并行计算设备的API以及一些声明计算内核的呢管理。软件开发人员可以利用OpenCL开发并行程序,并且可获得比较好的多种设备上运行的可移植性。

    为了使得OpenCL程序能够在各种硬件平台运行,OpenCL提供了一个硬件平台层,同时各种不同设备上的存储器并不相同,相应地,OpenCL提供了一个存储器抽象模型。不但包括一门编程语言,还包括一个完整的并行编程框架,通过编程语言、API以及运行时系统来支持软件在整个平台上的运行。

    异构并行计算的发展

    近年来,从私有的CUDA、C++AMP、Direct3D、Metal API,到开放的OpenCL、OpenACC、OpenGL。而传统的共享存储器编程环境OpenMP和分布式编程环境MPI也增加的对异构计算的支持。

    OpenCL的特点如下:

    • 高性能:OpenCL是一个底层的API,能够很好的映射到更底层的硬件上,充分发挥硬件中各个层次的并行性,故能够获得很好的性能。
    • 适用性强:OpenCL是一个抽象的API,抽象了当前主流的异构并行计算硬件的不同架构的共性,同时又兼顾了不同硬件的特点。
    • 开放:OpenCL是开发组件的开发、维护的标准,能够获得最广泛的硬件支持,如AMD、Intel、NVIDIA、ARM、Qualcomm和联发科等都已经或正在硬件是哪个支持OpenCL。

    MPI 3对异构并行计算的支持

    经典的分布式存储并行标准MPI在其版本3中明确了允许在数据传输函数调用时使用异构平台上的指针内容,并且同时在标准中扫清了相关的数据匹配等问题。这使得MPI在进行数据传输时,能够直接传递指向GPU或其他硬件上内存地址的指针。但是MPI 3对异构的支持几乎为0。

    OpenMP对异构并行计算的支持

    经典共享存储器并行编程环境OpenMP在其4.0版本标准中增加了很多支持异构计算的构造,如target、target data等。

    OpenCL无处不在

    AMD不但在其GPU上全面支持OpenCL,还在去X86 CPU上支持OpenCL,是第一个提供CPU+GPU全面支持OpenCL的厂家。AMD转向OpenCL后,和OpenCL的编程模型紧密结合,推出了GCN系统的GPU。Intel推出了其OpenCL支持方案,但是这种支持是全面的一劳永逸的,无论是Intel的X86 CPU,MIC GPU,还是Intel X86 CPU集成的GEN架构GPU都得到了支持。

    2013/2014,主流的移动处理器厂都退出了基于其移动GPU的OpenCL编译运行环境,如Imageination Technology的PowerVR系列移动GPU、高通的Adreno系列的移动GPU、ARM的Mali系统的GPU都支持了OpenCL。与此同时,主流的FPGA厂商Altera和Xilin也推出了OpenCL编译运行环境。

    展开全文
  • 异构并行计算工程师

    2018-11-18 17:34:42
    侵删,转载于, ... 随着深度学习(人工智能)的火热,异构并行计算越来越受到业界的重视。从开始谈深度学习必谈GPU,到谈深度学习必谈计算力。计算力不但和具体的...
    侵删,转载于, https://blog.csdn.net/qq_40027052/article/details/78810011

    随着深度学习(人工智能)的火热,异构并行计算越来越受到业界的重视。从开始谈深度学习必谈GPU,到谈深度学习必谈计算力。计算力不但和具体的硬件有关,且和能够发挥硬件能力的人所拥有的水平(即异构并行计算能力)高低有关。

    一个简单的比喻是:两个芯片计算力分别是10T和 20T,某人的异构并行计算能力为0.8,他拿到了计算力为10T的芯片,而异构并行计算能力为0.4的人拿到了计算力为20T的芯片,而实际上最终结果两人可能相差不大。异构并行计算能力强的人能够更好地发挥硬件的能力,而本文的目标就是告诉读者要变成一个异构并行计算能力强的工程师需要学习那些知识。

    异构并行计算是笔者提出的一个概念,它本质上是由异构计算和并行计算组合而来,一方面表示异构并行计算工程师需要同时掌握异构计算的知识,同时也需要掌握并行计算的知识;另一方面是为更好地发展和丰富异构计算和并行计算。通过异构并行计算进一步提升了知识的系统性和关联性,让每一个异构并行计算工程师都能够获得想要的工作,拿到值得的薪水。

    对于一个异构并行计算工程师的日常来说,他的工作涉及的方面很广,有硬件,有软件,有系统,有沟通;是一个对硬实力和软实力都有非常高要求的岗位。

    异构并行计算的难度是非常高的,而市场对这个职位的需求一直在提升,期待读者能够和我一起投身于异构并行计算的行列,为异构并行计算在中国的推广做出贡献。

    异构并行计算工程师技能树

    要想成为一个优秀的异构并行计算工程师需要掌握许多知识和技能,这些技能可以分为两个方面:

    1. 处理器体系,处理器如何执行具体的指令;
    2. 系统平台方面,这又可以分成多个细的主题,包括硬件的特点,软件编程相关的平台和基础设施。

    读者可以从图1具体了解到异构并行计算工程师需要掌握的技能和知识。

    图片描述

    图1 异构并行计算工程师技能树

    异构并行计算工程师成长详解

    每个人甚至每个技术领域都是在不停的成长,通常公司的岗位会区分为初级、中级、高级、主任等,这是按照贡献、能力和责任大小来分,并不适合用来表示技术。为了更好地帮助读者学习知识,本文从技能体系角度来分析,因此并不能对应到各个公司招聘的岗位需求上,也意味着读者不能简单的把本文的技能和各个公司的岗位级别对应。

    为了帮助读者更好地理解,本文会使用先硬件后软件的方式介绍。和异构并行工程师相关性最大的硬件知识即处理器特性,我们从这一点开始。

    现代处理器的特性

    从系统启动到终止,处理器一条接着一条地执行存储器中的指令,站在使用者的角度来看就好像是前一条指令执行完之后下一条指令才开始执行,是一个完完全全的串行过程。实际上,现代处理器利用了指令级并行技术,同一时刻存在着多条指令同时被执行,并且处理器执行指令的顺序无需和汇编代码给出的指令顺序完全一致,编译器和处理器只需要保证最终结果一致即可,这类处理器称为“乱序执行处理器”。而严格按照顺序一次执行一条指令,只有前一条执行完才开始执行后一条指令的处理器,称为“按序处理器”。而即使是在按序执行处理器上,编译器也可以对源代码进行类似的优化,以提高程序性能。对于一个特定的流水线来说,现代乱序执行处理器只保证指令执行阶段可以乱序,而其他阶段通常还是顺序的。目前主流的CPU和GPU,甚至DSP,无论是在服务器端,还是在移动端基本上都已经是乱序执行处理器了。

    今天大多数处理器都是哈佛架构的变体,其根本特征是在程序执行时把指令和数据分开存储,程序员通常可以忽略指令存储,实际上异构并行计算更关注的是:计算和数据访问。

    计算和访存

    以作者正在使用的处理器E5-2680v3来说,其主频为2.6GHz,支持FMA指令集,其单核单精度浮点计算能力为2.6*2*8*2=83.2 GFlops;而单通道内存的带宽大约为20GB/s。主流处理器的处理速度远快于内存读写速度,为了减小访问数据时的延迟,现代主流处理器主要采用了两种方式:

    • 利用程序访问数据的局部性特点:采用了一系列小而快的缓存保存正在访问和将要被访问的数据,如果数据会被多次访问且数据能够被缓存容纳,则能够以近似于内存的价格获得近似于缓存的速度;
    • 利用程序的并行性:在一个控制流由于高延迟的操作而阻塞时,执行另一个控制流,这样能够提高处理器核心的利用率,保证处理器核心一直在忙碌的状态。

    简单来说,前一种方法是将经常访问的数据保存在低延迟的缓存中,以减少访问数据时的延迟,通过更快为处理器提供数据而提高性能,主要是目前主流的CPU采用。而后一种方法则尽量保证运算单元一直在忙碌工作,通过提高硬件的利用率以提高程序的吞吐量,这种方法目前主要为主流的GPU所采用。这两种办法没有天然的壁垒,现代处理器(无论是CPU还是GPU)都采用了这两种方法,区别只是更偏重于使用哪一种方法。

    指令级并行

    现代处理器具有许多和代码性能优化相关的特点,本节主要介绍以下部分:

    • 指令级并行技术:主要有流水线、多发射、VLIW、乱序执行、分支预测、超标量等技术;
      向量化:主要有SIMT和SIMD技术;
    • 软件开发人员如果了解现代多核向量处理器的这些特性,就能写出性能效率超过一般开发人员的代码。

    多核

    多核是指一个CPU模块里包含多个核心,每个核心是一个独立的计算整体,能够执行线程。现代处理器都是多核处理器,并且为多核使用场景所优化。

    多核的每个核心里面具有独立的一级缓存,共享的或独立的二级缓存,有些机器还有独立或共享的三级/四级缓存,所有核心共享内存DRAM。通常第一级缓存是多核处理器的一个核心独享的,而最后一级缓存(Last Level Cache, LLC)是多核处理器的所有核心共享的,大多数多核处理器的中间各层也是独享的。如Intel Core i7处理器具有4~8个核,一些版本支持超线程,其中每个核心具有独立的一级数据缓存和指令缓存、统一的二级缓存,并且所有的核心共享统一的三级缓存。

    由于共享LLC,因此多线程或多进程程序在多核处理器上运行时,平均每个进程或线程占用的LLC缓存相比使用单线程时要小,这使得某些LLC或内存限制的应用的可扩展性看起来没那么好。

    由于多核处理器的每个核心都有独立的一级、有时还有独立的二级缓存,使用多线程/多进程程序时可利用这些每个核心独享的缓存,这是超线性加速(指在多核处理器上获得的性能收益超过核数)的原因之一。

    多路与NUMA

    硬件生产商还将多个多核芯片封装在一起,称之为多路,多路之间以一种介于共享和独享之间的方式访问内存。由于多路之间缺乏缓存,因此其通信代价通常不比DRAM低。一些多核也将内存控制器封装进多核之中,直接和内存相连,以提供更高的访存带宽。

    多路上还有两个和内存访问相关的概念:UMA(均匀内存访问)和NUMA(非均匀内存访问)。UMA是指多个核心访问内存中的任何一个位置的延迟是一样的,NUMA和UMA相对,核心访问离其近(指访问时要经过的中间节点数量少)的内存其延迟要小。如果程序的局部性很好,应当开启硬件的NUMA支持。

    硬件平台

    异构并行计算人员的能力最终需要通过运行在硬件上的程序来证明,这意味着异构并行计算编程人员对硬件的了解与其能力直接正相关。

    目前大家接触到处理器主要类型有:X86、ARM、GPU、FPGA等,它们的差别非常大。

    X86

    X86是Intel/AMD及相关厂商生产的一系列CPU处理器的统称,也是大家日常所见。X86广泛应用在桌面、服务器和云上。

    SSE是 X86 向量多核处理器支持的向量指令,具有16个长度为128位(16个字节)的向量寄存器,处理器能够同时操作向量寄存器中的16个字节,因此具有更高的带宽和计算性能。AVX将SSE的向量长度延长为256位(32字节),并支持浮点乘加。现在,Intel已将向量长度增加到512位。由于采用显式的SIMD编程模型,SSE/AVX的使用比较困难,范围比较有限,使用其编程是一件比较痛苦的事情。

    MIC是Intel的众核架构,它拥有大约60左右个X86核心,每个核心包括向量单元和标量单元。向量单元包括32个长度为512位(64字节)的向量寄存器,支持16个32位或8个64位数同时运算。目前的MIC的核为按序的,因此其性能优化方法和基于乱序执行的X86处理器核心有很大不同。

    为了减小使用SIMD指令的复杂度,Intel寄希望于其编译器的优化能力,实际上Intel的编译器向量化能力非常不错,但是通常手工编写的向量代码性能会更好。在MIC上编程时,软件开发人员的工作部分由显式使用向量指令转化为改写C代码和增加编译制导语句以让编译器产生更好的向量指令。

    另外,现代64位X86 CPU还利用SSE/AVX指令执行标量浮点运算。

    ARM

    目前高端的智能手机、平板使用多个ARM核心和多个GPU核心。在人工智能时代,运行在移动设备上的应用对计算性能需求越来越大,而由于电池容量和功耗的原因,移动端不可能使用桌面或服务器高性能处理器,因此其对性能优化具有很高需求。

    目前市场上的高性能ARM处理器主要是32位的A7/A9/A15,已经64位的A53/A57/A72。ARM A15 MP是一个多核向量处理器,它具有4个核心,每个核心具有64KB一级缓存,4个核心最大可共享2MB的二级缓存。ARM 32支持的向量指令集称为NEON。NEON具有16个长度为128位的向量寄存器(这些寄存器以q开头,也可表示为32个64位寄存器,以d开头),可同时操作向量寄存器的16个字节,因此使用向量指令可获得更高的性能和带宽。ARM A72 MP是一个多核向量处理器,其最多具有4个核心,每个核心独享32KB的一级数据缓存,四个核心最高可共享4MB统一的二级缓存。ARM 64支持的向量指令集称为asimd,指令功能基本上兼容neon,但是寄存器和入栈规则具有明显的不同,这意味着用neon写的汇编代码不能兼容asimd。

    GPU

    GPGPU是一种利用处理图形任务的GPU来完成原本由CPU处理(与图形处理无关的)的通用计算任务。由于现代GPU强大的并行处理能力和可编程流水线,令其可以处理非图形数据。特别在面对单指令流多数据流(SIMD),且数据处理的运算量远大于数据调度和传输的需要时,GPGPU在性能上大大超越了传统的CPU应用程序。

    GPU是为了渲染大量像素而设计的,并不关心某个像素的处理时间,而关注单位时间内能够处理的像素数量,因此带宽比延迟更重要。考虑到渲染的大量像素之间通常并不相关,因此GPU将大量的晶体管用于并行计算,故在同样数目的晶体管上,具有比CPU更高的计算能力。

    CPU和GPU的硬件架构设计思路有很多不同,因此其编程方法很不相同,很多使用CUDA的开发人员有机会重新回顾学习汇编语言的痛苦经历。GPU的编程能力还不够强,因此必须要对GPU特点有详细了解,知道哪些能做,哪些不能做,才不会出现项目开发途中发觉有一个功能无法实现或实现后性能很差而导致项目中止的情况。

    由于GPU将更大比例的晶体管用于计算,相对来说用于缓存的比例就比CPU小,因此通常局部性满足CPU要求而不满足GPU要求的应用不适合GPU。由于GPU通过大量线程的并行来隐藏访存延迟,一些数据局部性非常差的应用反而能够在GPU上获得很好的收益。另外一些计算访存比低的应用在GPU上很难获得非常高的性能收益,但是这并不意味着在GPU实现会比在CPU上实现差。CPU+GPU异构计算需要在GPU和CPU之间传输数据,而这个带宽比内存的访问带宽还要小,因此那种需要在GPU和CPU之间进行大量、频繁数据交互的解决方案可能不适合在GPU上实现。

    FPGA

    FPGA是现场可编程门阵列的缩写,随着人工智能的流行,FPGA越来越得到产业界和学术界的重视。FPGA的主要特点在于其可被用户或设计者重新进行配置,FPGA的配置可以通过硬件描述语言进行,常见的硬件描述语言有VHDL和verilog。

    使用VHDL和Verilog编程被人诟病的一点在于其编程速度。随着FPGA的流行,其编程速度越来越得到重视,各个厂商都推出了各自的OpenCL编程环境,虽然OpenCL降低了编程难度,但是其灵活性和性能也受到很大的限制。

    传统上,FPGA用于通信,现在FPGA也用于计算和做硬件电路设计验证。目前主流的两家FPGA厂商是Altera和Xilinx,Intel在2014年收购了Altera,估计在2018年,Intel X86+FPGA的异构产品会出现在市场。

    编程环境

    本节将详细介绍目前主流的并行编程环境,既包括常见的指令级并行编程技术,也包括线程级并行编程技术和进程级技术。

    Intel AVX/AVX512 Intrinsic

    SSE/AVX是Intel推出的用以挖掘SIMD能力的汇编指令。由于汇编编程太难,后来Intel又给出了其内置函数版本(intrinsic)。

    SSE/AVX指令支持数据并行,一个指令可以同时对多个数据进行操作,同时操作的数据个数由向量寄存器的长度和数据类型共同决定。如SSE4向量寄存器(xmm)长度为128位,即16个字节。如果操作float或int型数据,可同时操作4个,如果操作char型数据,可同时操作16个,而AVX向量寄存器(ymm)长度为256位,即32字节。

    虽然SSE4/AVX指令向量寄存器的长度为128/256 位,但是同样支持更小长度的向量操作。在64位程序下,SSE4/AVX 向量寄存器的个数是16个。

    SSE指令要求对齐,主要是为了减少内存或缓存操作的次数。SSE4指令要求16字节对齐,而AVX指令要求32字节对齐。SSE4及以前的SSE指令不支持不对齐的读写操作,为了简化编程和扩大应用范围,AVX指令支持非对齐的读写。

    ARM NEON Intrinsic

    NEON是ARM处理器上的SIMD指令集扩展,由于ARM在移动端得到广泛应用,目前NEON的使用也越来越普遍。

    NEON支持数据并行,一个指令可同时对多个数据进行操作,同时操作的数据个数由向量寄存器的长度和数据类型共同决定。

    ARMv7具有16个128位的向量寄存器,命名为q0~q15,这16个寄存器又可以分成32个64位寄存器,命名为d0~d31。其中qn和d2n、d2n+1是一样的,故使用汇编写代码时要注意避免寄存器覆盖。

    OpenMP

    OpenMP是Open Multi-Processing的简称,是一个基于共享存储器的并行环境。OpenMP支持C/C++/Fortran绑定,也被实现为库。目前常用的GCC、ICC和Visual Studio都支持OpenMP。

    OpenMP API包括以下几个部分:一套编译器伪指令,一套运行时函数,一些环境变量。OpenMP已经被大多数计算机硬件和软件厂商所接受,成为事实上的标准。

    OpenMP提供了对并行算法的高层的抽象描述,程序员通过在源代码中插入各种pragma伪指令来指明自己的意图,编译器据此可以自动将程序并行化,并在必要之处加入同步互斥等通信。当选择告诉编译器忽略这些pragma或者编译器不支持OpenMP时,程序又可退化为串行程序,代码仍然可以正常运作,只是不能利用多线程来加速程序执行。OpenMP提供的这种对于并行描述的高层抽象降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。对基于数据并行的多线程程序设计,OpenMP是一个很好的选择。同时,使用OpenMP也提供了更强的灵活性,可以适应不同的并行系统配置。线程粒度和负载均衡等是传统并行程序设计中的难题,但在OpenMP中,OpenMP库从程序员手中接管了这两方面的部分工作。

    OpenMP的设计目标为:标准、简洁实用、使用方便、可移植。作为高层抽象,OpenMP并不适合需要复杂的线程间同步、互斥及对线程做精密控制的场合。OpenMP的另一个缺点是不能很好地在非共享内存系统(如计算机集群)上使用,在这样的系统上,MPI更适合。

    MPI

    MPI(Message Passing Interface,消息传递接口)是一种消息传递编程环境。消息传递指用户必须通过显式地发送和接收消息来实现处理器间的数据交换。MPI定义了一组通信函数,以将数据从一个MPI进程发送到另一个MPI进程。在消息传递并行编程中,每个控制流均有自己独立的地址空间,不同的控制流之间不能直接访问彼此的地址空间,必须通过显式的消息传递来实现。这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采用的主要编程方式。实践表明MPI的扩展性非常好,无论是在几个节点的小集群上,还是在拥有成千上万节点的大集群上,都能够很好地应用。

    由于消息传递程序设计要求用户很好地分解问题,组织不同控制流间的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法。MPI是基于进程的并行环境。进程拥有独立的虚拟地址空间和处理器调度,并且执行相互独立。MPI设计为支持通过网络连接的机群系统,且通过消息传递来实现通信,消息传递是MPI的最基本特色。

    MPI是一种标准或规范的代表,而非特指某一个对它的具体实现,MPI成为分布式存储编程模型的代表和事实上的标准。迄今为止,所有的并行计算机制造商都提供对MPI的支持,可以在网上免费得到MPI在不同并行计算机上的实现,一个正确的MPI程序可以不加修改地在所有的并行机上运行。

    MPI只规定了标准并没有给出实现,目前主要的实现有OpenMPI、Mvapich和MPICH,MPICH相对比较稳定,而OpenMPI性能较好,Mvapich则主要是为了Infiniband 而设计。

    MPI主要用于分布式存储的并行机,包括所有主流并行计算机。但是MPI也可以用于共享存储的并行机,如多核微处理器。编程实践证明MPI的可扩展性非常好,其应用范围从几个机器的小集群到工业应用的上万节点的工业级集群。MPI已在Windows上、所有主要的UNIX/Linux工作站上和所有主流的并行机上得到实现。使用MPI进行消息传递的C或Fortran并行程序可不加改变地运行在使用这些操作系统的工作站,以及各种并行机上。

    OpenCL

    OpenCL(Open Computing Language,开放计算语言),先由Apple设计,后来交由Khronos Group维护,是异构平台并行编程的开放的标准,也是一个编程框架。Khronos Group是一个非盈利性技术组织,维护着多个开放的工业标准,并且得到了工业界的广泛支持。OpenCL的设计借鉴了CUDA的成功经验,并尽可能的支持多核CPU、GPU或其他加速器。OpenCL不但支持数据并行,还支持任务并行。同时OpenCL内建了多GPU并行的支持。这使得OpenCL的应用范围比CUDA广,但是目前OpenCL的API参数比较多(因为不支持函数重载),因此函数相对难以熟记。

    OpenCL覆盖的领域不但包括GPU,还包括其他的多种处理器芯片。到现在为止,支持OpenCL的硬件主要局限在CPU、GPU和FPGA上,目前提供OpenCL开发环境的主要有NVIDIA、AMD、ARM、Qualcomm、Altera和Intel,其中NVIDIA和AMD都提供了基于自家GPU的OpenCL实现,而AMD和Intel提供了基于各自CPU的OpenCL实现。目前它们的实现都不约而同地不支持自家产品以外的产品。由于硬件的不同,为了写出性能优异的代码,可能会对可移植性造成影响。

    OpenCL包含两个部分:一是语言和API,二是架构。为了C程序员能够方便、简单地学习OpenCL,OpenCL只是给C99进行了非常小的扩展,以提供控制并行计算设备的API以及一些声明计算内核的能力。软件开发人员可以利用OpenCL开发并行程序,并且可获得比较好的在多种设备上运行的可移植性。

    OpenCL的目标是一次编写,能够在各种硬件条件下编译的异构程序。由于各个平台的软硬件环境不同,高性能和平台间兼容性会产生矛盾。而OpenCL允许各平台使用自己硬件的特性,这又增大了这一矛盾。但是如果不允许各平台使用自己的特性,却会阻碍硬件的改进。

    CUDA

    CUDA认为系统上可以用于计算的硬件包含两个部分:一个是CPU(称为主机),一个是GPU(称为设备),CPU控制/指挥GPU工作,GPU只是CPU的协处理器。目前CUDA只支持NVIDIA的GPU,而CPU由主机端编程环境负责。

    CUDA是一种架构,也是一种语言。作为一种架构,它包括硬件的体系结构(G80、GT200、Fermi、Kepler)、硬件的CUDA计算能力及CUDA程序是如何映射到GPU上执行;作为一种语言,CUDA提供了能够利用GPU计算能力的方方面面的功能。CUDA的架构包括其编程模型、存储器模型和执行模型。CUDA C语言主要说明了如何定义计算内核(kernel)。CUDA架构在硬件结构、编程方式与CPU体系有极大不同,关于CUDA的具体细节读者可参考CUDA相关的书籍。

    CUDA以C/C++语法为基础而设计,因此对熟悉C系列语言的程序员来说,CUDA的语法比较容易掌握。另外CUDA只对ANSI C进行了最小的扩展,以实现其关键特性:线程按照两个层次进行组织、共享存储器(shared memory)和栅栏(barrier)同步。

    目前CUDA提供了两种API以满足不同人群的需要:运行时API和驱动API。运行时API基于驱动API构建,应用也可以使用驱动API。驱动API通过展示低层的概念提供了额外的控制。使用运行时API时,初始化、上下文和模块管理都是隐式的,因此代码更简明。一般一个应用只需要使用运行时API或者驱动API中的一种,但是可以同时混合使用这两种。笔者建议读者优先使用运行时API。

    编程模式

    和串行编程类似,并行编程也表现出模式的特征,并行编程模式是对某一类相似并行算法的解决方案的抽象。

    和串行编程类似,并行编程对于不同应用场景也有不同的解决方法。由于并行的特殊性,串行的解决方法不能直接移植到并行环境上,因此需要重新思考、设计解决方法。并行编程模式大多数以数据和任务(过程化的操作)为中心来命名,也有一些是以编程方法来命名。

    经过几十年的发展,人们已经总结出一系列有效的并行模式,这些模型的适用场景各不相同。本节将简要说明一些常用并行模式的特点、适用的场景和情况,具体的描述和实现则在后文详细描述。

    需要说明的是:从不同的角度看,一个并行应用可能属于多个不同的并行模式,本质原因在于这些并行模式中存在重叠的地方。由于模式并非正交,因此适用于一种模式的办法可能也适用于另一种模式,读者需要举一反三。

    任务并行模式

    任务并行是指每个控制流计算一件事或者计算多个并行任务的一个子任务,通常其粒度比较大且通信很少或没有。

    由于和人类的思维方式比较类似,任务并行比较受欢迎,且又易于在原有的串行代码的基础上实现。

    数据并行模式

    数据并行是指一条指令同时作用在多个数据上,那么可以将一个或多个数据分配给一个控制流计算,这样多个控制流就可以并行,这要求待处理的数据具有平等的特性,即几乎没有需要特殊处理的数据。如果对每个数据或每个小数据集的处理时间基本相同,那么均匀分割数据即可;如果处理时间不同,就要考虑负载均衡问题。通常的做法是尽量使数据集的数目远大于控制流数目,动态调度以基本达到负载均衡。

    数据并行对控制的要求比较少,因此现代GPU利用这一特性,大量减少控制单元的比例,而将空出来的单元用于计算,这样就能在同样数量的晶体管上提供更多的原生计算能力。

    基于进程的、基于线程的环境,甚至指令级并行环境都可以很好地应用在数据并行上。必要时可同时使用这三种编程环境,在进程中分配线程,在线程中使用指令级并行处理多个数据,这称为混合计算。

    异构并行计算领域现状

    在2005年之前,处理器通常提升频率来提升计算性能,由于性能是可预测的,因此在硬件生产商、研究人员和软件开发人员之间形成了一个良性循环。由于功耗的限制,处理器频率不能接着提升,硬件生产商转而使用向量化或多核技术。而以GPU计算为代表的异构并行计算的兴起,加上人工智能的加持,异构并行计算从学术界走向工业界,获得了大众的认可。今天几乎所有主流的处理器硬件生产商都已经在支持OpenCL,未来异构并行计算必将无处不在。今天无论上技术上还是市场上,它都获得了长足的发展,笔者可以预计在未来的十年,异构并行计算必将进一步深入发展,并且在更多的行业产生价值。

    技术进展

    由于工艺制程的影响,芯片的集成度提升会越来越难,现在14nm已经量产,未来7nm也将很快。随着制程技术到达极限,某些厂商通过制程领先一代的优势会消失,软件公司会进一步重视异构并行计算人才的价值。而一些硬件厂商会进化成系统厂商,不再只是提供单纯的硬件,进而会硬件和系统软件一起提供,通过把软件的成本转嫁到硬件上来获得利润。

    随着异构并行计算影响力的提升,各个厂商和组织开发了一系列的技术,如WebCL、OpenVX、Vulkan等。这些技术进一步丰富和扩张了异构并行计算的领域,更促进了异构并行计算。今天基本上每家硬件和系统软件公司都或多或少的涉及到了异构并行计算。

    市场需求

    随着人工智能的兴起,市场对异构并行计算领域人员的需求已经从传统的科学计算、图像处理转到互联网和新兴企业,目前人员缺口已经很大了,从51job和智联招聘上能够查到许多招聘信息。

    由于目前还在行业的早期,异构并行计算开发人员的能力和老板期望和支出之间存在明显的认知差距,再加上异构并行计算开发人员的工作成果往往需要和产品间接反应,故在多个层面上存在博弈。对于异构并行计算领域的人员来说,这个博弈有点不公平,因为职业特点要求异构并行计算领域的从业人员要比算法设计人员更了解算法实现细节、要比算法实现人员更了解算法的应用场景,再加上编程上的难度和需要付出更多的时间。但是由于行业刚形成不久,老板们并没有意识到这一点,他们还只是把异构并行计算从业人员当成普通的开发者,矛盾就产生了。

    随着人工智能的兴起,市场对异构并行计算从业人员的认知逐渐变得理性。越来越多的企业认识到:异构并行计算是人工智能企业最核心的竞争力之一。可以预见在不远的将来,异构并行计算工程师会越来越吃香。

    作者简介:
    刘文志,商汤科技高性能计算部门负责人,硕士毕业于中国科学院研究生院。曾于2011年至2014年间于英伟达担任并行计算工程师。后就职百度深度学习研究院高级研发工程师,负责异构计算组日常工作。
    责编:何永灿(heyc@csdn.net
    本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅《程序员》


    订阅程序员(含iOS、Android及印刷版)请访问 http://dingyue.programmer.com.cn
    这里写图片描述

    订阅咨询:

    • 在线咨询(QQ):2251809102
    • 电话咨询:010-64351436
    • 更多消息,欢迎关注“程序员编辑部
    展开全文
  • 异构并行计算技术参考资料:硬件软件 参考资料: 异构并行计算工程师技能树 硬件 软件
  • 基于异构并行计算模型的结构化光3D测量系统
  • opencl异构并行计算原理机制与优化实践 完整 pdf
  • OpenCL与异构并行计算

    千次阅读 2017-02-27 15:37:49
    OpenCL与异构并行计算
  • OPENCL+异构并行计算++原理、机制与优化实践,文字清晰,有目录
  • OpenCL异构并行计算:原理、机制与优化实践 此为试读书籍,不全,下载请注意
  • 课程主要研究异构编程、大规模并行处理器的概念、语言、方法和模式,自2012年首次发布以来,异构并行编程的内容和结构在此基础上得到了显著改进,其中包括并行计算架构、数据并行编程模式,内存带宽管理技术和并行...
  • 异构计算需求如何?对于异构并行计算领域的人员高付出高要求却是普遍低薪资的矛盾是怎么形成的?让我们来听听行业著名人士风辰怎么说.风辰:市场对异构并行计算领域人员的需求很大作者/来源: GPU World
  • 由于OpenCL标准本身阅读起来比较晦涩,很多概念也没有完全解释清楚,... 读者对象由于移动处理器和GPU已经非常便宜,而异构并行计算是未来的趋势,所有IT行业的从业者都应当收藏、阅读本书,以增加对OpenCL的了解。
  • 1.基于CUDA的异构并行计算 并行计算 并行计算通常涉及两个不同的计算技术领域。 计算机架构(硬件方面) 并行程序设计(软件方面) 计算机架构关注的是在结构级别上支持并行性,而并行编程设计关注的是充分使用计 ...
  • 《OPENCL异构并行计算》中讲了如何利用OPENCL进行卷积运算,并给出了使用局部存储器优化的例子,这里对其进行简单分析
  • 本节书摘来自华章计算机《CUDA C编程权威指南》一书中的第1章,第1.1节,作者 [美] 马克...基于CUDA的异构并行计算 本章内容: 了解异构计算架构 认识并行程序设计的范例转换 掌握GPU程序设计的基本要素 了解CPU和...
  • 《OPENCL异构并行计算》中讲了如何利用OPENCL进行矩阵乘法运算,并给出了使用局部存储器优化、使用向量加载指令以及一个工作项同时计算多个输出的例子,这里对其进行简单分析
  • 《OPENCL异构并行计算》中讲了如何利用使用同步锁的机制对各个工作组之间进行同步,这里对其进行简单分析
  • 当深度学习遇上异构并行计算 近几年来,以深度神经网络(DNN)为代表的深度学习如火如荼,深度学习的研究领域从开始的图像识别(如imagenet比赛)到现在的自然语言处理,几乎有席卷一切机器学习研究领域的趋势。 ...
  • OpenCL异构并行计算编程笔记(2):命令队列与内存对象
  • 并行计算 并行计算目标:提高运算速度 并行计算:同时使用许多计算资源(核心或计算机)来执行并发计算,一个大的问题可以被分解成多个小问题,然后在不同计算资源上并行处理这些小问题。 涉及2个不同的计算技术领域...
  • 这本书应该是国内首本由国人自己写的基于OpenCL 2.0的技术书吧。内容很不错,对OpenCL 2.0许多...而后面几章讲解了矩阵乘法等常规高性能计算的优化手法。作者非常耐心地讲解如何一步步对算法做深入优化并描述了调优过程
  • 《CUDA By Example》中文译名《GPU高性能编程CUDA实战》是研究GPGPU异构并行计算非常不错的工具书。书中给出的代码,非常个别的地方有失误,但是都有人为标注了,而且对不同的编程工具可能需要自己配置链接库。...
  • 《OpenCL异构并行计算:原理、机制与优化实践》笔记(一):OpenCL简介。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,815
精华内容 7,126
关键字:

异构并行计算