异构计算(CPU + GPU)编程简介

浅谈多节点CPU+GPU协同计算负载均衡性设计 近年来,基于CPU+GPU的混合异构计算系统开始逐渐成为国内外高性能计算领域的热点研究方向。在实际应用中,许多基于 CPU+GPU 的混合异构计算机系统表现出了良好的性能。但是,由于各种历史和现实原因的制约,异构计算仍然面临着诸多方面的问题,其中最突出的问题是程序开发困难,尤其是扩展到集群规模级别时这个问题更为突出。主要表现在扩展性、负载均衡、自适应性、通信、内存等方面。 一、    CPU+G 阅读详情

异构计算(CPU + GPU)编程简介

1.概念

所谓异构计算,是指CPU+ GPU或者CPU+ 其它设备(如FPGA等)协同计算。一般我们的程序,是在CPU上计算。但是,当大量的数据需要计算时,CPU显得力不从心。那么,是否可以找寻其它的方法来解决计算速度呢?那就是异构计算。例如可利用CPU(Central Processing Unit)、GPU(Graphic Processing Unit)、甚至APU(Accelerated Processing Units, CPU与GPU的融合)等计算设备的计算能力从而来提高系统的速度。异构系统越来越普遍,对于支持这种环境的计算而言,也正受到越来越多的关注。

2.异构计算的实现

目前异构计算使用最多的是利用GPU来加速。主流GPU都采用了统一架构单元,凭借强大的可编程流处理器阵容,GPU在单精度浮点运算方面将CPU远远甩在身后。英特尔Core i7 965处理器,在默认情况下,它的浮点计算能力只有NVIDIA GeForce GTX 280 的1/13,与AMD Radeon HD 4870相比差距就更大。

3.基于GPU编程

不同厂商通常仅仅提供对于自己设备编程的实现。对于异构系统一般很难用同种风格的编程语言来实现机构编程,而且将不同的设备作为统一的计算单元来处理的难度也是非常大的。基于GPU编程的,目前主要两大厂商提供:一个是NVidia,其提供的GPU编程为CUDA,目前使用的CUDA SDK 4.2.另一个是AMD,其提供的GPU编程为AMD APP (其前身是ATI Stream),目前最新版本 AMD APP 2.7。这两个东东是不兼容的,各自为政。作为软件开发者而言,用CUDA开发的软件只能在NVidia相应的显卡上运行,用AMD APP开发的软件,只能在ATI相应的显卡上运行。

4.OpenCL简介

那么有没有可能让他们统一起来,简化编程呢?有,那就是由苹果公司发起并最后被业界认可的OpenCL,目前版本1.2。

开放式计算语言(Open Computing Language:OpenCL),旨在满足这一重要需求。通过定义一套机制,来实现硬件独立的软件开发环境。利用OpenCL可以充分利用设备的并行特性,支持不同级别的并行,并且能有效映射到由CPU,GPU, FPGA(Field-Programmable Gate Array)和将来出现的设备所组成的同构或异构,单设备或多设备的系统。OpenCL定义了运行时, 允许用来管理资源,将不同类型的硬件结合在同种执行环境中,并且很有希望在不久的将来,以更加自然的方式支持动态地平衡计算、功耗和其他资源。

5. DirectCompute简介

作为软件行业的老大—微软在这方面又做了什么呢?微软也没闲着,微软推出DirectCompute,与OpenCL抗衡。DirectCompute集成在DX中,目前版本DX11,其中就包括DirectCompute。由于微软的地位,所以大多数厂商也都支持DirectCompute。

6.GPU计算模型

内核是执行模型的核心,能在设备上执行。当一个内核执行之前,需要指定一个 N-维的范围(NDRange)。一个NDRange是一个一维、二维或三维的索引空间。 还需要指定全局工作节点的数目,工作组中节点的数目。如图NDRange所示,全局工作节点的范围为{12, 12},工作组的节点范围为{4, 4},总共有9个工作组。

  

如果定义向量为1024维,特别地,我们可以定义全局工作节点为1024,工作组中节点为128,则总共有8个组。定义工作组主要是为有些仅需在组内交换数据的程序提供方便。当然工作节点数目的多少要受到设备的限制。如果一个设备有1024个处理节点,则1024维的向量,每个节点计算一次就能完成。而如果一个设备仅有128个处理节点,那么每个节点需要计算8次。合理设置节点数目,工作组数目能提高程序的并行度。

 

7.程序实例

不论是OpenCL还是DirectCompute,其编程风格都基本差不多,程序是分成两部分的:一部分是在设备上执行的(对于我们,是GPU),另一部分是在主机上运行的(对于我们,是CPU)。在设备上执行的程序或许是你比较关注的。它是OpenCL和DirectCompute产生神奇力量的地方。为了能在设备上执行代码,OpenCL程序员需要写一个特殊的函数(kernel函数)放在专用文件中(.cl),这个函数需要使用OpenCL语言编写。OpenCL语言采用了C语言的一部分加上一些约束、关键字和数据类型。在主机上运行的程序提供了API,所以可以管理你在设备上运行的程序。主机程序可以用C或者C++编写,它控制OpenCL的环境(上下文,指令队列…)。DirectCompute程序员需要写Shader文件(.hlsl),在这个文件中写函数。Shader文件的格式可以查MSDN。

在写程序时,先初始化设备,然后编译需要在GPU上运行的程序(运行在GPU上的程序是在应用程序运行时编译的)。然后映射需要在GPU上运行的函数名字,OpenCL 调用clEnqueueNDRangeKernel执行kernel函数,DirectCompute调用ID3D11DeviceContext:: Dispatch执行Shader函数。函数是并发执行的。

运行在GPU上的函数一般都很简单。以求和为例:

用CPU运算

void vector_add_cpu (const float* fIn1,

               const float* fIn2,

               float*  fOut,

               const int iNum)

{

   for (int i = 0; i < iNum; i++)

{

      fOut [i] = fIn1[i] + fIn2[i];

}

}

以下是OPenCL的kernel函数

//在GPU上,逻辑就会有一些不同。我们使每个线程计算一个元素的方法来代替cpu程序中的循环计算。每个线程的index与要计算的向量的index相同。

 

__kernel void vector_add_gpu (__global const float* fIn1,

                     __global const float* fIn2,

                     __global float* fOut,

           const int iNum)

{

   /* get_global_id(0) 返回正在执行的这个线程的ID。

   许多线程会在同一时间开始执行同一个kernel,

   每个线程都会收到一个不同的ID,所以必然会执行一个不同的计算。*/

   const int idx = get_global_id(0);

 

   /* 每个work-item都会检查自己的id是否在向量数组的区间内。

   如果在,work-item就会执行相应的计算。*/

   if (idx < iNum)

{

        fOut [idx] = fIn1[idx] + fIn2[idx];

}

}

有一些需要注意的地方:

1. Kernel关键字定义了一个函数是kernel函数。Kernel函数必须返回void。

2. Global关键字位于参数前面。它定义了参数内存的存放位置。

另外,所有kernel都必须写在“.cl”文件中,“.cl”文件必须只包含OpenCL代码。

 

Shader函数

#define NUM_THREAD 16

StructuredBuffer<float> fInput1 : register( t0 );

StructuredBuffer<float> fInput2 : register( t0 );

StructuredBuffer<float> fOutput : register( u0 );

 

[numthreads(NUM_THREAD, 1, 1)]

void vector_add_gpu( uint3 Gid : SV_GroupID,

            uint3 DTid : SV_DispatchThreadID,

            uint3 GTid : SV_GroupThreadID,

            uint GI : SV_GroupIndex )

{

   fOutput[DTid.x] =  fInput1[DTid.x]  + fInput2[DTid.x] ;

}

图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度, 通常是指绕图像的中心以逆时针方向旋转。假设图像的左上角为(l, t), 右下角为(r, b),则图像上任意点(x, y) 绕其中心(xcenter, ycenter)逆时针旋转θ角度后, 新的坐标位置(x',y')的计算公式为:

 

x′ = (x - xcenter) cosθ - (y - ycenter) sinθ + xcenter,

 

y′ = (x - xcenter) sinθ + (y - ycenter) cosθ + ycenter.

 

C代码:

void image_rotate(

        unsigned int* iInbuf,

        unsigned int* iOutbuf,

        int iWidth, int iHeight,

        float fSinTheta,

        float fCosTheta)

{

   int i, j;

   int iXc = iWidth /2;

   int iYc = iHeight /2;

   for(i = 0; i < iHeight; i++)

   {

      for(j=0; j< iWidth; j++)

      {

        int iXpos =  (j- iXc)*fCosTheta - (i - iYc) * fSinTheta + iXc;

        int iYpos =  (j- iXc)*fSinTheta + (i - iYc) * fCosTheta + iYc;

        if(iXpos >=0&& iYpos >=0&& iXpos < iWidth  && iYpos < iHeight)

           iOutbuf[iYpos * iWidth  + iXpos] = iInbuf[i* iWidth  +j];

      }

   }

}

CL代码:

__kernel  void image_rotate(

                    __global int * iInbuf,

                    __global int * iOutbuf,        //Data in global memory

                    int iWidth  ,    int iHeight,                   //Image Dimensions

                    float fSinTheta, float fCosTheta )   //Rotation Parameters

{

   const int ix = get_global_id(0);

   const int iy = get_global_id(1);

   int iXc = iWidth  /2;

   int iYc = iHeight /2;

   int iXpos =  ( ix- iXc)*fCosTheta - (iy- iYc)*fSinTheta+ iXc;

   int iYpos =  (ix- iXc)*fSinTheta + ( iy- iYc)*fCosTheta+ iYc;

   if ((iXpos >=0) && (iXpos < iWidth  )   && (iYpos >=0) && (iYpos < iHeight))

      iOutbuf[iYpos * iWidth  + iXpos]= iInbuf[iy* iWidth  +ix];

}

 

不论是OpenCL还是 DirectCompute,其编程还是有些复杂,特别是对于设备的初始化,以及数据交换,非常麻烦。对于初学者难度相当大。那么有没有更简单的编程方法呢?

8.C++AMP

还要提到微软,因为我们基本上都使用微软的东东。微软也不错,推出了C++AMP,这是个开放标准,嵌入到VS2012中(VS2012目前还是预览版),在Win7和Win8系统中才能使用,其使用就简单多了:

 

#include <amp.h>

using namespace concurrency;

 

const int size = 5;

 

void CppAmpMethod()

{

   int aCPP[] = {1, 2, 3, 4, 5};

   int bCPP[] = {6, 7, 8, 9, 10};

   int sumCPP[size];

 

   // Create C++ AMP objects.

   array_view<const int, 1> a(size, aCPP);

   array_view<const int, 1> b(size, bCPP);

   array_view<int, 1> sum(size, sumCPP);

   sum.discard_data();

 

   parallel_for_each(

      // Define the compute domain, which is the set of threads that are created.

      sum.extent,

      // Define the code to run on each thread on the accelerator.

      [=](index<1> idx) restrict(amp)

   {

      sum[idx] = a[idx] + b[idx];

   }

   );

 

}

就这么简单,只需要包含一个头文件,使用一个命名空间,包含库文件,一切就OK,在调用时,只是一个函数parallel_for_each。(有点类似OpenMP)。

 

9.应用

MATLAB 2010b中Parallel Computing Toolbox与MATLAB Distributed Computing Server的最新版本可利用NVIDIA的CUDA并行计算架构在NVIDIA计算能力1.3以上的GPU上处理数据,执行GPU加速的MATLAB运算,将用户自己的CUDA Kernel函数集成到MATLAB应用程序当中。另外,通过在台式机上使用Parallel Computing Toolbox以及在计算集群上使用MATLAB Distributed Computing Server来运行多个MATLAB worker程序,从而可在多颗NVIDIA GPU上进行计算。AccelerEyes公司开发的Jacket插件也能够使MATLAB利用GPU进行加速计算。Jacket不仅提供了GPU API(应用程序接口),而且还集成了GPU MEX功能。在一定程度说,Jacket是一个完全对用户透明的系统,能够自动的进行内存分配和自动优化。Jacket使用了一个叫“on-the- fly”的编译系统,使MATLAB交互式格式的程序能够在GPU上运行。目前,Jacket只是基于NVIDIA的CUDA技术,但能够运行在各主流操作系统上。

从Photoshop CS4开始,Adobe将GPU通用计算技术引入到自家的产品中来。GPU可提供对图像旋转、缩放和放大平移这些常规浏览功能的加速,还能够实现2D/3D合成,高质量抗锯齿,HDR高动态范围贴图,色彩转换等。而在Photoshop CS5中,更多的算法和滤镜也开始支持GPU加速。另外,Adobe的其他产品如Adobe After Effects CS4、Adobe Premiere Pro CS4也开始使用GPU进行加速。这些软件借助的也是NVIDIA的CUDA技术。

Windows 7 的核心组成部分包括了支持GPU通用计算的Directcompute API,为视频处理、动态模拟等应用进行加速。Windows 7借助Directcompute增加了对由GPU支持的高清播放的in-the-box支持,可以流畅观看,同时CPU占用率很低。Internet Explorer 9加入了对Directcompute技术的支持,可以调用GPU对网页中的大计算量元素做加速计算;Excel2010、Powerpoint2010也开始提供对Directcompute技术的支持。

比利时安特卫普大学,通用电气医疗集团,西门子医疗,东芝中风研究中心和纽约州立大学水牛城分校的都针对GPU加速CT重建进行了各自的研究,不仅如此,西门子医疗用GPU实现了加速MRI中的GRAPPA自动校准,完成MR重建,快速MRI网格化,随机扩散张量磁共振图像(DT-MRI)连通绘图等算法。其他的一些研究者则把医学成像中非常重要的二维与三维图像中器官分割(如Level Set算法),不同来源图像的配准,重建体积图像的渲染等也移植到GPU上进行计算。

10 .不足

异构并行计算变得越来越普遍,然而对于现今存在的OpenCL和 DirectCompute版本来说,的确还存在很多不足,例如编写内核,需要对问题的并行情况做较为深入的分析,对于内存的管理还是需要程序员来显式地申明、显式地在主存和设备的存储器之间进行移动,还不能完全交给系统自动完成。从这些方面,OpenCL和 DirectCompute的确还需加强,要使得人们能高效而又灵活地开发应用,还有很多工作要完成。

 

CPU+GPU异构计算编程简介 阅读详情

相关推荐

OpenCL的多GPU和多核CPU异构计算--1

本文主要探究OpenCL的GPU和多核CPU的异构计算问题,主要简要阐述了什么是OpenCL异构计算,讲述CPU和GPU各自的特点,并且把他们结合起来做异构计算的前景。然后具体讲述在高性能实验室Linux工作站上如何搭建多GPU和多核CPU异构OpenCL环境。最后用实验验证了所安装的OpenCL异构计算环境能够正常工作,说明什么是OpenCL的多GPU与多核CPU异构环境的platform,de

飞鸿惊雪 3766

AI加速(六)| 异构编程——性能不够,“外挂“来凑?

异构编程可以认为是一种使用专用芯片对神经网络进行加速的外挂方式。通过这种专用的加速卡,来完成神经网络中相关算法的加速运算。其实,异构编程并不是一个很新的概念。据一个从事手机开发的朋友讲,他们很早之前做手机,手机系统中会有很多不同的芯片,主处理器和协处理之间都会有通信,某些算法在主处理器上跑,某些算法在协处理器上跑,最终完成一个整体运算。这就是一种异构编程,只不过当时他们认为这是理所当然的。而随着人工智能的热潮,异构编程这一概念才越来越多的被人所熟知。从而也成为了AI加速中一个不可或缺的编程方式。

通俗易懂的 AI 技术 1794

【异构计算平台系列 - GPU + OpenCL - 02】异构计算(Heterogeneous Computing)简介

What? 异构计算(Heterogeneous computing)主要是指使用不同类型指令集和体系架构的计算单元组成系统的计算方式。 常见的计算单元类别包括CPU、GPU等协处理器、DSP、ASIC(Application Specific Integrated Circuit)、FPGA等。 从实现的角度来说,异构计算就是制定出一系列的软件与硬件的标准,让不同类型的计算设备能够共享计算...

星辉领域 3559

CUDA 异构并行计算与编程模型

CUDA从入门到放弃

小鹏AI 2247

OpenCL的多GPU和多核CPU异构计算--2

本文主要探究OpenCL的GPU和多核CPU的异构计算问题,主要简要阐述了什么是OpenCL异构计算,讲述CPU和GPU各自的特点,并且把他们结合起来做异构计算的前景。然后具体讲述在高性能实验室Linux工作站上如何搭建多GPU和多核CPU异构OpenCL环境。最后用实验验证了所安装的OpenCL异构计算环境能够正常工作,说明什么是OpenCL的多GPU与多核CPU异构环境的platform,de

飞鸿惊雪 3424

【异构计算架构】CPU/GPU/FPGA混合资源池

随着摩尔定律的物理极限逼近,单一架构的计算芯片已无法满足高并发、高吞吐场景的需求。异构计算通过整合CPU、GPU、FPGA等多种处理器,实现了“专业分工+协同增效”的计算范式。其发展历程从早期的GPU图形渲染和FPGA固定功能加速卡,到2010-2020年的CUDA生态和FPGA布局,再到2020年后的资源池化阶段,逐步形成了动态资源池。技术特点包括资源多样性、任务协同机制和灵活性与能效。实现细节涉及资源池化架构、调度算法优化和典型案例。未来发展趋势包括架构革新、生态整合和行业标准化。异构计算正推动算力供给

沐风—云端行者 1996

常见异构程序设计语言

主要对混合架构的常见异构编程语言进行介绍(OpenMP、MPI、CUDA/HIP、Athread、OpenACC、OpenCL、oneAPI)

欢迎各位大佬光临“寒舍”!请多多指点,共同进步! 1398

深入理解CPU和异构计算芯片GPU/FPGA/ASIC (上篇)

随着互联网用户的快速增长,数据体量的急剧膨胀,数据中心对计算的需求也在迅猛上涨。诸如深度学习在线预测、直播中的视频转码、图片压缩解压缩以及HTTPS加密等各类应用对计算的需求已远远超出了传统CPU处理器的能力所及。摩尔定律失效的今天,关注“新“成员(GPU\FPGA\ASIC)为数据中心带来的体系架构变革,为业务配上一台动力十足的发动机。 1 异构计算:WHY 明明CPU用的好好的,为

Qcloud_KID的博客 9499

异构计算综述

异构计算(Heterogeneous computing)异构计算(Heterogeneous computing)技术从80年代中期产生,由于它能经济有效地获取高性能计算能力、可扩展性好...

OpenFPGA的博客 1万+

异构编程和cuda程序概念

异构编程和cuda程序概念

puqian13的博客 865

异构计算 — CPU+GPU

目录 文章目录目录CPU-GPU 异构计算系统分离式架构 CPU-GPU 异构计算系统 在现代的异构计算系统中,GPU 是以 PCIe 卡的形式作为 CPU 的辅助计算设备。根据 CPU 和 GPU 是否共享了内存,可分为两种类型的 CPU-GPU 异构计算架构: 分离式架构:CPU 和 GPU 拥有各自独立的缓存和内存,两者之间通过 PCIe 总线通信。目前主要做计算机、智能手机中使用。 耦合式架构:CPU 和 GPU 共享内存和缓存。AMD 的 APU 采用的就是这种结构,目前主要使用在游戏主机中。

烟云的计算 7076

基于CPU+GPU的异构计算

GPU GPU是为了视频游戏而产生的(至今其主要驱动力还是不断增长的视频游戏市场),在三维游戏中常常出现的一类操作是对海量数据进行相同的操作,如:对每一个顶点进行同样的坐标变换,对每一个顶点按照同样的光照模型计算颜色值。 GPU的众核架构非常适合把同样的指令流并行发送到众核上,采用不同的输入数据执行 CUDA CUDA和C程序并无区别,只是多了一些以“CUDA”开头的库函数。 使用CUD...

ICT产业论坛 1328

OpenHarmony-AI调研

基于OpenHarmony-5.0.0版本以及laval社区等网络资料调研当前OH上的AI发展情况。

qqq1112345的博客 1369

异构计算 CPU、GPU、DSP、ASIC、FPGA

异构计算主要是指使用不同类型指令集和体系架构的计算单元组成系统的计算方式。异构计算已经无处不在,从超算系统到桌面到云到终端,都包含不同类型指令集和体系架构的计算单元,下面先从几个系统了解下异构计算超算系统。天河-2:包括16,000个计算节点,每个节点 2*Xeon (IveBridge)+3*Phi。Total 3,120,000 Core, Linpack测试基准为33.86 petaFLOPS ,Power 17.6 megawatts。编程框架:OpenMC/OpeMP。Mac Pro: Intel

心静思远 2846

从MRF8P9040N数据手册到ADS仿真:手把手教你搞定LDMOS功放设计(附完整模型下载)

本文详细解析了MRF8P9040N LDMOS功率放大器的数据手册关键参数,并提供了在ADS中进行仿真的完整指南。从模型导入、直流工作点验证到负载牵引与阻抗匹配设计,逐步指导工程师完成高效功放设计。文章还包含调试技巧和常见问题解决方案,帮助优化射频功放性能。

weixin_27015733的博客 489

ArcMap安装与配置全攻略:从下载到实战应用

本文提供了ArcMap 10.4.1从系统准备、详细安装到破解激活的完整指南,并包含首次启动的界面介绍与一个实战GIS分析项目。针对初学者,文章强调了在ArcGIS Pro成为趋势的当下,学习经典ArcMap对于理解核心概念和兼容现有工作流仍有重要价值,帮助用户避开安装常见陷阱,快速上手实战应用。

weixin_29200741的博客 338

异构计算‌:结合CPU和GPU的优势,通过CUDA实现异构编程,优化任务分配。

异构计算通过整合CPU、GPU等不同架构处理器实现高效计算,核心在于任务合理分配:CPU处理控制密集型任务(逻辑控制、I/O操作),GPU负责计算密集型任务(矩阵运算、深度学习)。关键技术包括CUDA编程模型、显式内存管理和并行线程优化。典型应用场景涵盖科学计算(气候模拟)、人工智能(模型训练)、图形渲染(3D建模)等领域,可实现数十倍性能提升。当前面临硬件协同、编程复杂性、性能优化等挑战,未来将向统一内存抽象和智能调优方向发展。

Made In SQL 1645

大学计算 - NumPy库的矩阵运算 实训答案

本文介绍了三个NumPy矩阵操作的实验练习。第一关练习ndarray类型操作,包括矩阵构造、元素平方和计算、矩阵乘积运算和逆矩阵行列式计算;第二关针对matrix类型,涉及绝对值最大值获取、特定矩阵乘积运算和转置矩阵特征值计算;第三关实现Moore-Penrose伪逆矩阵计算,并与NumPy内置pinv函数结果比较误差。实验涵盖了NumPy核心矩阵操作,展示了从基础运算到高级矩阵分解的应用,帮助掌握科学计算中的矩阵处理技巧。

2403_89314916的博客 310
下一篇: OpenCL使用GPU滤波
IDDIALOG
博客等级 码龄23年 39粉丝 7原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值