Tags: GPU

对应《GPU高性能编程CUDA实战中文版》第1-3章笔记。

CUDA开发环境配置

CUDA全称是Compute Unified Device Architecture。 CUDA开发环境配置十分简单,只需要去官网(点击进入)下载对应安装包,解压、安装即可。安装完成后即可使用。
CUDA安装界面

基础概念

我们将CPU以及系统的内存称为主机,将GPU及其内存称为设备。在GPU设备上执行的函数通常叫做核函数(Kernel)。一个简单的例子:

__global__ void kernel(void)
{
  //Your code here...
}

int main(void)
{
  kernel<<<1,1>>>();
  printf("Hello world!\n");
  return 0;
}

与我们熟悉的C语言相比,多了两样东西:

  • 一个空的函数kernel(),并且带有修饰符__global__(注意是两个下划线,不是一个)
  • main()函数中对这个函数的调用,并且带有修饰符«<1,1»>

CUDA C为标准C增加了__global__这个修饰符,它将告诉编译器,函数 应该编译为在设备而不是主机上运行。在这段代码中,函数kernel() 将被交给编译设备代码的编译器,而main()函数将被交给主机编译器。

给核函数传递参数

__global__ void add(int a, int b, int *c)
{
  *c = a + b;
}

int main()
{
  int c;
  int * dev_c;
  cudaMalloc((void **)&dev_c, sizeof(int));
  add <<<1, 1 >>>(2, 7, dev_c);
  cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost);
  printf("2+7=%d\n", c);
  cudaFree(dev_c);
  return 0;
}

在本段代码中,定义了一个add()的核函数,a、b为值传递,c为引用传递。 调用核函数的过程为定义一个指针,为该指针在GPU内存上分配空间, 调用GPU进行计算,将结果由GPU内存拷贝至主机内存,最后释放掉GPU对应的内存。 需要注意的是,不能使用标准的C的free()函数来释放cudaMalloc()分配的内存。 要释放cudaMalloc()分配的内存,需要调用cudaFree()

查询设备

可以使用cudaGetDeviceCount()查询CUDA设备的数量,返回int。调用方式如下:

int count;
cudaGetDeviceCount(&count);
printf("%d\n",count);

在获得设备数后,可对每个设备进行迭代,获取各自的相关信息。 可以利用cudaGetDeviceProperties()函数获取,返回为cudaDeviceDrop()类型的数据。 其中包含各种信息。下面代码可以实现对每个设备信息的迭代:

cudaDeviceProp prop;
int count;
cudaGetDeviceCount(&count);
for(int i=0;i<count;i++)
{
  cudaGetDeviceProperties(&prop,i);
  printf("%s\n",prop.name);
  //......Your code......
}

部分设备属性如下:
name:char,标识设备的ASC字符串,如“GeForce GTX 1080”
totalGlobalMem:size_t,设备上全局内存的总量,单位为字节
totalConstMem:size_t,常量内存的总量
major:int,设备计算功能集(Compute Capability)的主版本号
minor:int,设备计算功能集的次版本号
deviceOverlap:boolean,一个布尔类型值,表示设备是否可以同时执行一个 cudaMemory()调用和一个核函数调用
multiProcessorCount:int,设备上多处理器的数量

总结

从本质上来说CUDA C只是对标准C进行了语言级的扩展,通过增加 一些修饰符使我们可以指定哪些代码在设备上运行,哪些代码在 主机上运行。在函数前添加关键字_global_将告诉编译器把 该函数放在GPU上运行。与C类似,CUDA C中依然有cudaMalloc()cudaMemcpy()cudaFree(),分别实现分配设备内存,在设备 和主机之间复制数据,以及释放内存等操作。

本文作者原创,未经许可不得转载,谢谢配合

返回顶部