并行计算之路<6>——CUDA的软件架构

入门和gpu相关知识。作为开篇应该在完美不过了。
阅读《CUDA专家手册》第三章硬件架构后的一个笔记。之所以将目录都打出来,因为这就是CUDA的软件架构。

软件层

从应用程序本身到CUDA硬件上执行的CUDA驱动程序。
这里写图片描述
驱动程序API和CUDA运行时中的函数名称分别以cu*()和cuda*()大头。3对尖括号<<<>>>为启用内核函数。

CUDA运行时和驱动程序

驱动程序版本可由cuDriverGetVersion()函数获取。

驱动程序模型

  • 统一虚拟寻址
  • Windows显式驱动模型
  • 超时检测与恢复
  • 特斯拉计算集群驱动程序

nvcc, PTX和微码

  • nvcc是CUDA开发者使用的编译器驱动程序。例如编译、链接。
    这里写图片描述
  • 并行线程执行(PTX, Parallel Thread eXecution)代码是编译后的GPU代码的一种中间形式,它可以再次编译为原生的GPU微码。

设备与初始化

设备数量

调用cuDeviceGetCount()或cudaGetDeviceCount()函数查询范围为[0…DeviceCount - 1]的设备可用。

设备属性

  • cuDeviceGetName()->查询设备名称
  • cuDeviceTotalMem()->查询全局内存
  • cuDeviceComputeCapability()->查询计算能力
  • cuDeviceAttribute()->查询设备属性
  • cudaGetDeviceProperties()->返回包括设备名称和属性信息的结构体cudaDeviceProp

无CUDA支持情况

CUDA运行时程序可以运行在不能运行CUDA的机器或未安装CUDA的机器上。如果cudaGetDeviceCount()函数返回cudaSuccess和一个非0的设备数,CUDA是可以用的。

上下文

上下文类似CPU中的进程,管理CUDA程序中所有对象生命周期的容器,包括如下部分:

  • 所有内存分配(线性设备内存,主机内存,CUDA数组)
  • 模块
  • CUDA流
  • CUDA事件
  • 纹理与表面引用
  • 使用本地内存的内核的设备内存
  • 进行调试、分析、同步操作时,所使用的内部资源
  • 换页内存复制所使用的锁定中转缓冲区

cudaSetDevice()函数,为调用的线程设置当前上下文。

生命周期与作用域

所有与CUDA上下文相关的分配资源都在上下文被销毁的同时被销毁。

资源预分配

少数情况下,CUDA不会预分配一个给定操作所需的全部资源。

地址空间

一组私有的虚拟内存地址,它可以分配线性设备内存或用以映射锁页主机内存。

当前上下文栈

三个主要功能。
- 单线程应用程序可以驱动多个GPU上下文
- 库可以创建并管理它们自己上下文,而不需要干涉调用者的上下文。
- 库不知晓调用它的CPU线程信息。
当前上下文栈的最初动机是使单线程CUDA应用程序可以驱动多个CUDA上下文。

上下文状态

类似于CPU中的malloc()和printf()函数,cuCtxSetLimit()和cuCtxGetLimit()函数可以设置和获取内核函数中对应函数的GPU空间上限。cuCtxSetCacheConfig()函数在启动内核时指定所期望的缓存配置。

模块与函数

模块是代码与一同加载的数据的集合,类似于windows中的动态链接库(DLL)和Linux中的动态共享对象(DSO)。模块只在CUDA驱动程序API中可用。
模块被加载,应用程序就可以查询其中包含的资源:
- 全局资源
- 函数(内核)
- 纹理引用

内核(函数)

在.cu文件中,用global标识内核。三对尖括号<<<>>>为启用内核函数。

设备内存

设备内存(或线性设备内存)驻留在CUDA地址空间上,可以被CUDA内核通过标准C/C++指针和数组解引用操作访问。CUDA硬件并不支持请求式换页,所以,所有的内存分配被真实的物理内存支持着。CUDA内存分配在物理内存耗尽时会失败。

流与事件

【CUDA】cuda stream和event相关内容

流与事件使主机与设备之间的内存复制与内核操作可并发执行。
CUDA流被用来粗粒度管理多个处理单元的并发执行:

  • GPU/CPU
  • 在SM处理时可以执行DMA操作的复制引擎
  • 流处理器蔟(SM)
  • 并发内核
  • 并发执行的独立GPU

流的操作是按顺序执行的,像CPU的线程。

软件流水线

软件流水线解决因只有一个DMA引擎服务于GPU各种各样的粗粒度硬件资源,应用软件必须对多流中执行的操作进行流水操作。
开普勒架构减少了软件流水线操作的需求,Hyper-Q技术实际上消除了流水线需求。

流回调

不懂。

NULL流

NULL流失GPU上所有引擎的集结地,所有的流内存复制函数都是异步的。NULL流最有用的场合是在不需要使用多流来利用GPU内部的并发性时,它可以解决应用程序的CPU/GPU并发。一旦流操作使用NULL流初始化,应用程序必须使用同步函数来确保操作在执行下一步之前完成。

事件

CUDA事件表示了另一个同步机制。同CUDA流一同引入,记录CUDA事件是CUDA流中应用程序跟踪进度的一个方式。当之前的所有CUDA流的操作执行结束后,全部的CUDA事件通过写入一个共享同步内存位置而起作用。

主机内存

主机内存(CPU内存)。在所有运行CUDA的操作系统上,主机内存是虚拟化的。
为了便利DMA,操作系统VMM(虚拟内存管理器)提供了一个页面锁定功能。被VMM标记为锁页的内存就不能被换出,所以物理内存地址不能被修改。没被锁页的内存称作可换页。

锁页主机内存

锁页主机内存由CUDA函数cuMemHostAlloc()/cudaHostAlloc()分配。该内存是页锁定的并且由当前CUDA上下文为DMA设置。异步内存复制操作只在锁页内存上工作。
在CUDA中,锁页内存(pinned memory)是经过页锁定后且为硬件访问而映射后的主机内存,而页面锁定(page-locking)只是操作系统的一种不允许换页的机制。但是在操作系统文档中,这个两个概念是同义的。

可分享的锁页内存

可分享页内存在页锁定后映射给所有CUDA上下文。

映射锁页内存

映射锁页内存映射到CUDA上下文中的地址空间中,所以内核可能读写这块内存。

主机内存注册

用于开发者分配他们想要访问的内存。

CUDA数组与纹理操作

纹理引用可以把输入的任何坐标转化到设置的输出格式,表面引用则暴露了一个常规的逐位操作接口来读写CUDA数组内容。

纹理引用

纹理引用是CUDA用来设置纹理硬件解释实际内存内容的对象。

表面引用

表面引用可以是CUDA内核使用表面加载/存储内建函数读写CUDA数组。

图形互操作性

图形互操作性函数族使得CUDA可以读写属于OpenGL或Direct3D API的内存。

CUDA运行时与CUDA运动程序API

驱动程序API没有提供任何性能优势,但它为应用程序提供了显式的资源管理。

尾巴

草草结束该章内容,没有实际的操作真得让人很容易犯困。最后用一句话结束尾巴的内容——“当一位作家略去他所不知道的东西时,它们在作品中像漏洞似的显示出来。”

参考:
《GPGPU编程技术——从GLSL、CUDA到OpenCL》♥♥♥♥♥
《数字图像处理高级应用——基于MATLAB与CUDA的实现》♥♥♥
《基于CUDA的并行程序设计》♥♥♥
《CUDA专家手册》♥♥♥♥♥
《高性能CUDA应用设计与开发》♥♥♥♥

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值