您的位置:首页 > 运维架构 > 网站架构

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

2016-02-23 17:14 423 查看
入门和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应用设计与开发》♥♥♥♥
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: