技术开发 频道

CUDA基础

  【IT168 技术】1.在一个CUDA程序中,基本的主机端代码主要完成以下任务

  1) 启动CUDA,使用多卡时加上设备号,或者使用cudaDevice()设置GPU装置。

  2) 分别在CPU和GPU端分配内存,用以储存输入输出数据,CPU端要记得初始化数据,然后将数据拷入显存。

  3) 调用device端的kernel程序计算,将结果写到显存相关区域,再回写到内存。

  4) 利用CPU进行数据其他处理,释放内存和显存空间。

  5) 退出CUDA装置

  2.CUT_DEVICE_INIT(argc,argv)和CUT_EXIT(argc,argv)是cutil.h中的两个宏函数,分别用来启动和退出CUDA环境。

  3. 昨天提到了CUDA_SAFE_CALL()宏函数,调用后的返回值为cudaerr型,用CUT_CHECK_ERROR()宏函数可以接受最后一次的 cudaerr_t异常,如果发生异常将输出错误类型,对调试很有帮助,cudaerr_t是定义在toolkit里的\include \drive_types.h中。

  4.我们知道在使用完内存和显存空间后要释放。另外,为了防止指针指飞现象,最好在程序结束后将指针赋空并摧毁。

  5.Kernel函数完整的执行参数配置形式<<

  1) Dg用于定义整个grid的维度和尺寸,为dim3型。最多为二维,Dg.x和Dg.y最大为65535,整个grid中最多也只能定义65535个block。

  2) Db用于定义每个block的维度和大小,也是dim3型。Db.x和Db.y最大为512,Db.z最大为4,三个维度之积小于768(计算能力为1.0,1.1的硬件)或1024(计算能力为1.2,1.3的硬件)

  3) Ns是一个可选参数,用于设置每个block除了静态分配的shared memory外,最多能动态分配的shared memory,单位是Byte。目前的硬件最多每个block分配16KB的shared memory(静态+动态)。不需要时可写0或省略。

  4) S是一个cudaStream_t类型的可选参数,初始值为0.

  6.看过CUDA程序的都知道啊,进行一次GPU计算,需要在多个存储器之间进行数据传输,因此有较大的延迟,故而GPU不适合对实时性要求很高的应用。由于不同存储器间的数据传输速率和使用方法有很大差异,故而开发人员需要根据硬件特点设计并行算法。

  7.到目前为止,我觉得最难的地方就是要根据任务以及硬件的特对任务进行划分,以设计block的工作流程,既要照顾到数据传输的问题同时要隐藏各种访存延迟。

  8.关于extern限定符:在_device_和_global_函数中表示动态分配,而在主机端正如C语言所描述的一样,只是表示外部变量。注意:通过这种方式定义的所有变量都是开始于同一地址,因此数组中的变量布局必须通过偏移量显式管理。

  如要在动态分配的共享存储器中得与下代码对应内容

  short array0[128];

  float array1[64];

  int array2[256];

  应该按照如下方式定义

   extern_shared_char array[];

     _device_void func()
//_device_or_glabol_function

     {  
short*array0=(short*)array;

        
float*array1=(float*)array0[128];

        
int*array2=(int*)array1[64];

    }

  9.注意到后面附的两个kernel程序都包含了#ifndef_EXAMPLE_1_KERNEL_H_和#define_EXAMPLE_1_KERNEL_H_两个头文件,在#includeemu模式下包含这两个,是为了输出一些中间结果来观察,GPU运行时不能使用。

  10.在第二个程序的kernel程序中还有一个宏#define SDATA(index) CUT_BANK_CHECKER(sdata,index)。这是调用cutil在emu模式下检查shared memory bank conflict的宏函数。

  11.注意到使用了CUDA自带的库函数_mul24()完成两个数的相乘。在CUDA中,GPU端(release和debug模式下的_global_和_device_函数)只能使用自带的数学库函数。

  说明:有前缀“_”的函数根据SP特点进行了优化,可获得更高的速度,但是有前缀“_”的整数程序只能处理24位整数,有前缀“_”的浮点数精度较不带该前缀的版本精度要差一些。

  12. 在本文后面附有的关于matrixAssign的两个程序的第二个中用到了CUDA_SAFE_CALL(cudaMallocHost)和 CUDA_SAFE_CALL(cudaFreeHost)函数,这意味着主机端使用了pinned memory。关于它的更多更详细介绍且听下回分解。

  两个程序下载

0
相关文章