前言

本篇只是对CUDA入门有一个宏观的概述,并不涉及具体编程细节,是关于CUDA基础信息的科普性文章,适用于想简单了解什么是CUDA,以及对CUDA工作流程感兴趣的小伙伴。


一、初识CUDA

1.1 什么是CUDA

CUDA是一种由NVIDIA公司推出的通用并行计算架构。它的主要目的是让开发者能够利用GPU(的强大计算能力来进行通用计算,这种计算方式通常被称为GPGPU(General-Purpose computing on Graphics Processing Units)。CUDA提供了一种并行程序模型,允许开发者定义并控制大量的并行线程的执行,这些线程可以被组织成线程块和线程组。CUDA核心是运行在这些线程上的特殊函数,它们能够在GPU上并行执行任务。

在这里插入图片描述

  • CUDA

    Compute Unified Device Architecture

  • 基于C/C++的编程方法

  • 支持异构编程的扩展方法(下方会介绍异构编程)

  • 拥有简单明了的APIs,能够轻松的管理存储系统,能更快更好地使用GPU

  • CUDA支持的编程语言:

    C/C++/Python/Fortran/Java/…

在这里插入图片描述
如上图所示,在整个计算机体系中,最底层自然是由CPU、GPU等硬件组成的

硬件之上就是操作系统及其相关驱动接口

咱们的CUDA在整个计算机里呢是位于系统层之上的

而我们所需要学习的则是在CUDA的更上一层(上图红框所示)

也就是说,我们是在CUDA基础之上进行并行计算设计和数值方法处理,我们调用CUDA及其相关接口去完成一系列的APP应用设计。


1.2 异构计算

在NVIDIA的GPU上进行编程任务,我们需要了解什么是GPU与异构计算。

了解GPU的异构计算,我们需要对CPU和GPU有明显的区分,需要搞清楚下面的两个概念(术语)。

  • Host CPU和内存(host memory)
  • Device GPU和显存(device memory)

其实我们的GPU刚开始是叫做协处理器,它并不是单独的在计算机中去执行任务,而是去协助我们的CPU乃至整个计算机系统去完成一个整体任务。

如下图所示,我们把5%甚至更少的代码量放到GPU上去跑,虽然代码量少,但是执行的计算任务却很多。把更多的计算任务放到我们的GPU上,让GPU和CPU一起协作完成任务,这就是所谓的异构计算的一部分。

在这里插入图片描述

总的来说,所谓异构,是指CPU、DSP、GPU、ASIC、协处理器、FPGA等各种计算单元、使用不同的类型指令集、不同的体系架构的计算单元,组成一个混合系统来执行计算。

有了这个概念打底,可以为后续我们学习CUDA编程,区分CPU代码GPU代码做基础。


1.3 CUDA安装

这上面提供的连接是NVIDIA官方提供的教程,Windows下的安装很简单,就直接执行一个.exe可执行文件就可以了,Jetson安装直接刷机即可。

相对于Windows和Jetson来说,Linux下安装CUDA略加复杂一点,参照网上其他人的安装教程,可能有一些时间比较久的会有一些坑,存在一些问题,这里建议NVIDIA官方最新教程进行安装,就会简单许多。

我这里用Edge浏览器的翻译,翻译成中文一般不会存在太多的问题,如果发现个别语句不太通顺就需要小伙伴自己检查一下原文了。

在这里插入图片描述


二、CUDA程序的编写

2.1 CUDA代码示例

下方是一个CUDA代码例程,我们以CUDA C为基础,将CPU代码和GPU代码混写在一起,也可以说是将串行代码和并行代码混写在一起,我们只需要完成整个代码文件,然后通过nvcc编译程序,将代码编译为计算机可执行的二进制文件。

通过CUDA,我们不需要单独编写CPU程序和GPU程序,只需要将它们写入同一个文件,nvcc就会帮我们完成剩下的工作。

在这里插入图片描述


2.2 CUDA程序执行流程

将CUDA程序编写好后,我们需要明确,我们的GPU是协处理器,所以我们需要CPU和GPU一起工作,相互协作来完成程序任务。

首先第一步,我们需要在CPU端将我们需要处理的数据复制到GPU端。

在这里插入图片描述
然后在第二步中,相关的数据就会在GPU端的存储系统通过分级存储器调进CUDA核进行计算处理。

在这里插入图片描述
第三步,我们就将GPU计算好的数据复制回CPU中。

在这里插入图片描述

概括来说,就是CPU将数据复制进GPU完成计算,然后将计算结果复制回CPU这样一个流程。


2.3 CUDA重要关键字

这里介绍几个CUDA中重要的三个关键字。

关键字执行位置调用位置
__device__float DeviceFunc()devicedevice
__global__void KernelFunc()devicehost&device(arch>3.0)
__host__float HostFunc()hosthost

注意:上方表格关键字左右两侧的下划线都是两个下划线

上方表格最左侧的一列写的是关键词,右侧两列分别是对应关键词的额执行位置和调用位置。

  • 例如 _global_定义一个 Kernel 函数
    -入口函数,可以在CPU上调用,必须在GPU上执行
    -必须返回void

  • _device_ 和 _|host_ 可以同时调用

下图是一个简单的CUDA程序示例,包括了GPU函数的编写及调用。
在这里插入图片描述

下一篇链接:CUDA学习入门(二)


本人是一名学生,也是正在学习Jetson的过程中,如有错误请批评指正!

部分图表信来源:https://mp.weixin.qq.com/s/em309Ho6AaV5f1ogWpajJw

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐