CUDA入门

cuda veyvin 1751℃ 0评论
文章目录[隐藏]
本文最后更新于2020年8月2日 13:09,如果文章内容失效,请反馈给我们,谢谢!

为了让程序利用GPU进行并行运算. 可以利用Nvidia 提供的CUDA.学习新的知识最权威的当然是官方提供的文档

简单的CUDA helloworld.cu 程序


刚看到这个程序时,我们通常会对<<<1,1024>>> 感到奇怪.我们会想这样的写法我们熟知的编译器可没有这种语义结构,那这段程序用什么编译的呢?

– 从上往下阅读,有个cuda_runtime.h头文件,我们搜索官方文档,会发现这个头文件是host端(CPU)运行时,他提供了

  1. device (GPU)管理
  2. context管理
  3. 内存管理
  4. 代码模块管理
  5. 纹理引用管理
  6. 与OpenGL和Direct3D 互操作

其他的库如cuBLAS(贝叶斯) cuFFT(快速傅里叶变换)也依赖于cuda runtime

cuda_runtime.h(C++-style?) 还有个父亲叫cuda_runtime_api.h(C-style)


继续往下看__global__ 是什么?

在一个函数前面用 __global__限定符:表示将一个函数声明为内核

  1. 表明这个函数在device(GPU)上执行
  2. 可以从host(CPU)调用
  3. 可以从device(GPU)调用cc3.2以上的device(GPU)

这个函数必须是 void 返回类型

执行该函数必须指定调用该函数的配置,即下面的<<<1,1024>>>

对__global__ 函数的调用是异步的,这意味着device在执行完之前返回


<<<1,1024>>> 是什么?

官方称这个叫 执行配置,那配置里面的参数都是什么意思

通过上面的链接我们发现 格式是这个样子的<<< Dg, Db, Ns, S >>>

  1. Dg类型为dim3 指定了 grid的维度和大小 Dg.x*Dg.y*Dg.z 等于启动的 block
  2. Db类型为dim3 指定了 block的维度和大小 Db.x*Db.y*Db.z 等于每个block启动的thread数量
  3. Ns类型为size_t?可选参数,?程序中我们除了静态分配内存外,利用这个函数可以为每个block 动态分配共享内存 number of bytes in shared memory,默认为0
  4. S类型为cudaStream_t 可选参数,?指定关联的流默认为0

这里我们涉及了grid,block,thread, memory 和stream.这些知识以后会讲解.

上面的<<<1,1024>>>如何配置的参数超过了自己机器上的限制,或者共享内存超过了限制,函数调用失败.

查看机器上的参数阈值是多少?

不同的GPU 计算能力可能不一样,通过上面这个链接的表查看参数的限制.也可以通过其他工具查看.


最后我们试着在VS上跑一下这个程序,并人为制造一些bug看一下.

执行后输出了1024条helloworld

修改<<<1,1024>>>为<<<1,1025>>>,程序正常执行,没有输出任何东西

修改<<<1,1024>>>为<<<2147483648,1>>>程序正常执行,没有输出任何东西

修改<<<1,1024>>>为<<<2,2>>> 输出4条

总结:由于Dg和Db我们这样写相当于一个一维的数,即Dg.y?Dg.z Db.y?Db.z 我们并没有指定.<<<1,1025>>> 由于我的GPU Db.x 阈值为1024,写成1025超过了,当然不调用kernel函数 其他同理, 并行执行的总数当然是Dg*Db.

转载请注明:veyvin » CUDA入门

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址