首页 > 其他分享 >编写CUDA核函数验与证核函数杂谈

编写CUDA核函数验与证核函数杂谈

时间:2024-08-29 12:47:54浏览次数:7  
标签:__ 函数 res void float CUDA 证核

编写核函数 核函数也是一个函数,但是声明核函数有一个比较模板化的方法: global__ void kernel_name(argument list); 注意:声明和定义是不同的,这点CUDA与C语言是一致的 在C语言函数前没有的限定符global,CUDA C中还有一些其他在C中没有的限定符,见表10-2。 表10-2 CUDA C中一些其他在C中没有的限定符

限定符

执行

调用

备注

__global__

设备端执行

可以从主机调用也可以从计算能力3以上的设备调用

必须有一个void的返回类型

__device__

设备端执行

设备端调用

 

__host__

主机端执行

主机调用

可以省略

有些函数可以同时定义为 device 和 host,这种函数可以同时被设备和主机端的代码调用,主机端代码调用函数很正常,设备端调用函数与C语言一致,但是要声明成设备端代码,告诉nvcc编译成设备机器码,同时声明主机端设备端函数,那么就要告诉编译器,生成两份不同设备的机器码。 Kernel核函数编写有以下限制 1)只能访问设备内存 2)必须有void返回类型 3)不支持可变数量的参数 4)不支持静态变量 5)显示异步行为 并行程序中经常的一种现象:把串行代码并行化时对串行代码块for的操作,也就是把for并行化。
例如:
    串行: void sumArraysOnHost(float *A, float *B, float *C, const int N) {   for (int i = 0; i < N; i++)     C[i] = A[i] + B[i]; } 并行: global__ void sumArraysOnGPU(float *A, float *B, float *C) {   int i = threadIdx.x;   C[i] = A[i] + B[i]; } 这两个简单的段不能执行,但是可以大致的看一下for展开并行化的样子。 验证核函数 验证核函数就是验证其正确性,下面这段代码上文出现过,但是同样包含验证核函数的方法: /* * 3_sum_arrays */ #include <cuda_runtime.h> #include <stdio.h> #include "freshman.h"     void sumArrays(float * a,float * b,float * res,const int size) {   for(int i=0;i<size;i+=4)   {     res[i]=a[i]+b[i];     res[i+1]=a[i+1]+b[i+1];     res[i+2]=a[i+2]+b[i+2];     res[i+3]=a[i+3]+b[i+3];   } } __global__ void sumArraysGPU(float*a,float*b,float*res) {   int i=threadIdx.x;   res[i]=a[i]+b[i]; } int main(int argc,char **argv) {   int dev = 0;   cudaSetDevice(dev);     int nElem=32;   printf("Vector size:%d\n",nElem);   int nByte=sizeof(float)*nElem;   float *a_h=(float*)malloc(nByte);   float *b_h=(float*)malloc(nByte);   float *res_h=(float*)malloc(nByte);   float *res_from_gpu_h=(float*)malloc(nByte);   memset(res_h,0,nByte);   memset(res_from_gpu_h,0,nByte);     float *a_d,*b_d,*res_d;   CHECK(cudaMalloc((float**)&a_d,nByte));   CHECK(cudaMalloc((float**)&b_d,nByte));   CHECK(cudaMalloc((float**)&res_d,nByte));     initialData(a_h,nElem);   initialData(b_h,nElem);     CHECK(cudaMemcpy(a_d,a_h,nByte,cudaMemcpyHostToDevice));   CHECK(cudaMemcpy(b_d,b_h,nByte,cudaMemcpyHostToDevice));     dim3 block(nElem);   dim3 grid(nElem/block.x);   sumArraysGPU<<<grid,block>>>(a_d,b_d,res_d);   printf("Execution configuration<<<%d,%d>>>\n",block.x,grid.x);     CHECK(cudaMemcpy(res_from_gpu_h,res_d,nByte,cudaMemcpyDeviceToHost));   sumArrays(a_h,b_h,res_h,nElem);     checkResult(res_h,res_from_gpu_h,nElem);   cudaFree(a_d);   cudaFree(b_d);   cudaFree(res_d);     free(a_h);   free(b_h);   free(res_h);   free(res_from_gpu_h);     return 0; } 在开发阶段,每一步都进行验证是绝对高效的,比把所有功能都写好,然后进行测试这种过程效率高很多,同样写CUDA也是这样的每个代码小块都进行测试,看起来慢,实际会提高很多效率。
CUDA小技巧,当进行调试的时候可以把核函数配置成单线程的: kernel_name<<<1,1>>>(argument list)

标签:__,函数,res,void,float,CUDA,证核
From: https://www.cnblogs.com/wujianming-110117/p/18386450

相关文章

  • 错误处理、cuda模型、GPU架构杂谈
    错误处理、cuda模型、GPU架构杂谈错误处理所有编程都需要对错误进行处理,早起的编码错误,编译器会帮搞定,内存错误也能观察出来,但是有些逻辑错误很难发现,甚至到了上线运行时才会被发现,而且有些厉害的bug复现会很难,不总出现,但是很致命,而且CUDA基本都是异步执行的,当错误出现的时候,不......
  • CUDA编程结构、存储管理、线程管理杂谈
    CUDA编程结构、存储管理、线程管理杂谈CUDA编程结构一个异构环境,通常有多个CPU多个GPU,他们都通过PCIe总线相互通信,也是通过PCIe总线分隔开的。所以要区分一下两种设备的内存:1)主机:CPU及其内存2)设备:GPU及其内存这两个内存从硬件到软件都是隔离的(CUDA6.0以后支持统一寻址),目前先......
  • C#学习笔记- 随机函数Random()的用法详解
    原文链接:https://www.jb51.net/article/90933.htmRandom.Next()返回非负随机数;Random.Next(Int)返回一个小于所指定最大值的非负随机数Random.Next(Int,Int)返回一个指定范围内的随机数,例如(-100,0)返回负数1、random(number)函数介绍random(number)返回一个0~number-1之间......
  • 用MySQL的GROUP_CONCAT函数轻松解决多表联查的聚合问题
    大家好呀,我是summo,最近遇到了一个功能需求,虽然也是CURD,但属于那种比较复杂一点的CURD,话不多说,我们先看一下需求。需求如下:有三张表,学生表、课程表、学生课程关联表,关联关系如下图:要求实现的功能:支持输入名称模糊查询,可以是学生名称也可以是课程名称,但只有一个输入框;要求以......
  • Python——集合基本操作以及哈希函数
    Python中的集合(Set)是一个无序的、不包含重复元素的数据结构。集合主要用于数学上的集合操作,如并集、交集、差集和对称差集等。集合使用大括号 {} 来表示,但注意空集合不能使用 {} 表示(这会创建一个空字典),而应该使用 set() 来创建。创建集合1.使用大括号 {}:这是最直接......
  • PHP8面向对象快速入门三 类的继承 类方法属性重写和final关键字 parent调用父类的方法
    在PHP中,类的继承(继承)是一种机制,允许一个类继承另一个类的属性和方法,从而实现代码的重用和扩展。继承可以帮助你创建一个基于现有类的新类,保留原有类的特性并增加或修改其功能。classAnimal{public$name='dongwu';protected$age=1;private......
  • 【C++基础】多种函数重载和运算符重载
    目录一、函数重载1.参数类型不同的重载讲解2.参数个数不同的重载讲解3.参数顺序不同的重载讲解4.默认参数与函数重载讲解二、运算符重载1.运算符重载的基本语法示例讲解函数内部的操作:运算符的使用:2.运算符重载的常见用法2.1重载<<和>>运算符(用于输......
  • 【CUDA编程笔记】如何使用CUDA统一内存来优化多进程多线程程序的性能?
    如何使用CUDA统一内存来优化多进程多线程程序的性能?要使用CUDA统一内存优化多进程多线程程序的性能,可以采取以下步骤。理解统一内存统一内存是CUDA编程模型的一个组件,它定义了一个所有处理器都可访问的单一连贯内存映像,允许数据在CPU和GPU之间透明迁移,无需显式复制。使......
  • switch&回调函数
    #include<stdio.h>//函数原型声明floatcalc(floata,floaty,constcharop);floatadd(floata,floatb);floatminus(floata,floatb);floatmultiple(floata,floatb);floatdivide(floata,floatb);floatcalc_using_callback(floata,floatb,floa......
  • YOLOv9改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题
    一、本文介绍本文记录的是改进YOLOv9的损失函数,将其替换成SlideLoss,并详细说明了优化原因,注意事项等。SlideLoss函数可以有效地解决样本不平衡问题,为困难样本赋予更高的权重,使模型在训练过程中更加关注困难样本。若是在自己的数据集中发现容易样本的数量非常大,而困难样本......