当前位置: 首页 > 网络知识

CUDA 简单程序的基本框架和自定义设备函数

时间:2026-01-29 09:25:02

1 cuda程序的基本框架

框架包含:

1 int main() 2

示例代码如下。

1 #include<math.h> 2 #include<stdio.h> 3 const double EPSILON=1.0e15; 4 const double a=1.23; 5 const double b=2.34; 6 const double c=3.57; 7 void __global__ add(const double *x,const double *y,double *z); 8 void check(const double *z,const int N); 9 int main(void) 10 21 double *d_x,*d_y,*d_z; 22 cudaMalloc((void **)&d_x,M); 23 cudaMalloc((void **)&d_y,M); 24 cudaMalloc((void **)&d_z,M); 25 cudaMemcpy(d_x,h_x,M,cudaMemcpyHostToDevice); 26 cudaMemcpy(d_y,h_y,M,cudaMemcpyHostToDevice); 27 const int block_size=128; 28 const int grid_size=N/block_size; 29 add<<<grid_size,block_size>>>(d_x,d_y,d_z); 30 cudaMemcpy(h_z,d_z,M,cudaMemcpyHostToDevice); 31 check(h_z,N); 32 free(h_x); 33 free(h_y); 34 free(h_z); 35 cudaFree(d_x); 36 cudaFree(d_y); 37 cudaFree(d_z); 38 return 0; 39 } 40 void __global__ add(const double *x,const double *y,double *z) 41 45 void check(const double *z,const int N) 46 54 printf("%s\n",has_error?"Has errors":"No errors"); 55 } 56 }

1.1 隐形的设备初始化
  在cuda运行时API中,没有明显地初始化设备(GPU)的函数。在第一次调用一个和设备管理及版本管理及版本查询功能无关的运行时API函数时,设备将自动地初始化。

1.2 设备内存的分配与释放
  在上述程序中,我们首先在主机中定义了三个数组并进行了初始化,通过cudaMalloc函数将它们指向了设备中的内存,而不是主机的内存。该函数是一个cuda运行时API函数,所有cuda运行时API函数都以cuda开头。
  在c++中由malloc()函数动态分配内存,在cuda中,设备内存的动态分配可由cudaMalloc()函数实现,函数原型如下。
  cudaError_t cudaMalloc(void **address,size_t size);

  调用cudaMalloc()函数时传入的第一个参数(void *)&d_x比较难懂。其中d_x是一个double类型的指针,他的地址就是指针的指针,也就是双重指针,而使用(void * * )是一个强制类型转换操作。转换为void类型的双重指针。这种类型的转换可以不明确的写出来。所以cudaMalloc()函数的调用也可以简写为 cudaMalloc(&d_x,M);
  用cudaMalloc()函数为什么需要一个双重指针作为变量呢?该函数的功能是改变指针d_x本身的值(将一个指针赋值给d_x),而不是改变d_x所指内存缓冲区中的变量值。需要将d_x的地址&d_x传给函数cudaMalloc()才能达到修改指针d_x本身的值的效果。
  总之,使用cudaMalloc函数可以为不同类型的指针变量分配设备内存。为了区分主机和设备中的变量,使用d_作为所有设备变量的前缀,使用h_作为对应主机变量的前缀。
  正如mallloc()函数分配的主机内存需要使用free()释放一样,用cudaMalloc()函数分配的设备内存需要用cudaFree()函数释放。该函数原型为cudaError_t cudaFree(void address);
  这里参数address就是待释放的设备内存变量(不是双重指针),返回值是一个错误代号。

1.3 主机与设备之间数据的传递
  在分配了设备内存之后,就可以将一些数据从主机传递到设备中去,使用cudaMemcpy()方法主机中的变量数据复制到设备中相应变量d_x和d_y所指向的缓冲区中。其方法的原型是。

1.4 核函数的要求

2 自定义设备函数
  核函数可以调用不带执行配置的自定义函数,这样的自定义函数称为设备函数。他是在设备中执行,并在设备中调用的。与之相比,核函数是在设备中执行,但是在主机端被调用的。

2.1函数执行空间表示符

2.2 代码示例

1 double __device__ add1_device(const double x, const double y) 2 5 void __global__ add1(const double *x, const double *y, double *z, 6 const int N) 7 13 }



上一篇:Qt 编写CUDA程序
下一篇:C++ Boost库简介
CUDA
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素