CUDA C编程接口技术分析

编程接口

CUDA C为熟悉C编程语言的用户提供了一个简单的路径,可以方便地编写程序供设备执行。

它由C语言的最小扩展集和运行库组成。

核心语言扩展已经引入:cuda c programming guide。它们允许程序员将内核定义为C函数,并在每次调用该函数时使用一些新语法来指定网格和块维度。任何包含这些扩展名的源文件都必须用nvcc编译。

在编译工作流中引入了运行时。它提供在主机上执行的C函数,用于分配和解除分配设备内存、在主机内存和设备内存之间传输数据、管理具有多个设备的系统等。运行时的完整描述可在CUDA参考手册中找到。

运行时构建在较低级别的C API(CUDA驱动程序API)之上,应用程序也可以访问该API。驱动程序API通过公开较低级别的概念(如CUDA上下文——设备的主机进程模拟)和CUDA模块——设备的动态加载库模拟,提供了额外的控制级别。大多数应用程序不使用驱动程序API,因为它们不需要这种额外的控制级别,并且在使用运行时,上下文和模块管理是隐式的,从而产生更简洁的代码。驱动程序API在驱动程序API中介绍,并在参考手册中详细描述。

1. 使用NVCC编译

内核可以使用CUDA指令集体系结构(称为PTX)编写,PTX参考手册中对此进行了描述。然而,使用高级编程语言(如C)通常更有效。在这两种情况下,内核必须由nvcc编译成二进制代码才能在设备上执行。

nvcc是一个编译器驱动程序,它简化了编译C或PTX代码的过程:它提供简单而熟悉的命令行选项,并通过调用实现不同编译阶段的工具集合来执行这些选项。本节概述了nvcc工作流和命令选项。完整的描述可以在nvcc用户手册中找到。

1.1. 编制工作流程

1.1.1.离线编译

用nvcc编译的源文件可以包括主机代码(即,在主机上执行的代码)和设备代码(即,在设备上执行的代码)的混合。nvcc的基本工作流程是将设备代码与主机代码分离,然后:

·将设备代码编译为汇编形式(PTX代码)和/或二进制形式(cubin对象),

·修改宿主代码,用必要的CUDA C运行时函数调用替换内核中引入的语法(并在执行配置中详细描述),以便从PTX代码和/或cubin对象加载和启动每个编译的内核。

修改后的主机代码输出为C代码,该代码将留在使用另一个工具编译时使用,或者通过让nvcc在最后一个编译阶段调用主机编译器直接作为目标代码输出。

应用程序可以:

·链接到已编译的主机代码(这是最常见的情况),

·或者忽略修改后的主机代码(如果有的话),并使用CUDA驱动程序API(请参阅驱动程序API)来加载和执行PTX代码或cubin对象。

1.1.2. 及时编译

应用程序在运行时加载的任何PTX代码都由设备驱动程序进一步编译为二进制代码。这称为即时编译。即时编译增加了应用程序加载时间,但允许应用程序从每个新设备驱动程序带来的任何新编译器改进中获益。这也是应用程序在编译应用程序时不存在的设备上运行的唯一方法,如应用程序兼容性中所述。

当设备驱动程序及时为某个应用程序编译一些PTX代码时,它会自动缓存生成的二进制代码的副本,以避免在随后的应用程序调用中重复编译。当设备驱动程序升级时,缓存(称为计算缓存)会自动失效,因此应用程序可以从设备驱动程序中内置的新实时编译器的改进中获益。

环境变量可用于控制CUDA环境变量中描述的实时编译。

1.2.二进制兼容性

二进制代码是特定于体系结构的。cubin对象是使用指定目标体系结构的编译器选项-code生成的:例如,使用-code=sm_35编译会为具有计算能力3.5的设备生成二进制代码。二进制兼容性保证从一个小版本到下一个小版本,但不是从一个小版本到上一个小版本或跨主要版本。换句话说,为计算能力X.y生成的cubin对象将只在计算能力X.z的设备上执行,其中z≥y。

1.3. PTX兼容性【PTX兼容性】

某些PTX指令仅在具有更高计算能力的设备上受支持。例如,Warp Shuffle函数仅在计算能力为3.0及以上的设备上受支持。-arch编译器选项指定在编译C到PTX代码时假设的计算能力。例如,包含warp shuffle的代码必须使用-arch=compute_30(或更高版本)编译。

为某些特定计算能力生成的PTX代码始终可以编译为具有更大或同等计算能力的二进制代码。请注意,从早期PTX版本编译的二进制文件可能无法使用某些硬件功能。例如,从为计算能力6.0(Pascal)生成的PTX编译的计算能力7.0(Volta)的二进制目标设备将不会使用张量核心指令,因为这些指令在Pascal上不可用。因此,最终的二进制文件的性能可能比使用最新版本的PTX生成的二进制文件的性能差。

1.4. 应用程序兼容性

要在具有特定计算能力的设备上执行代码,应用程序必须加载与此计算能力兼容的二进制或PTX代码,如二进制兼容性和PTX兼容性中所述。特别是,为了能够在具有更高计算能力的未来架构上执行代码(还不能生成二进制代码),应用程序必须加载PTXcode,该PTXcode将为这些设备及时编译(请参阅及时编译)。

哪个PTX和二进制代码嵌入到CUDA C应用程序中,由-arch和-code编译器选项或-gencode编译器选项控制,如nvcc用户手册中所述。例如,

嵌入与计算能力3.5和5.0(第一和第二gencode选项)兼容的二进制代码,以及与计算能力6.0(第三gencodepoption)兼容的PTX和二进制代码。

生成宿主代码是为了在运行时自动选择要加载和执行的最合适的代码,在上面的示例中,将是:

·3.5计算能力为3.5和3.7的设备的二进制代码,

·5.0计算能力为5.0和5.2的设备的二进制代码,

·6.0计算能力为6.0和6.1的设备的二进制代码,

·PTX代码,在运行时为具有计算能力7.0及更高版本的设备编译为二进制代码。

x.cu可以有一个优化的代码路径,使用warp shuffle操作,例如,只有计算能力3.0及更高的设备才支持这种操作。可以使用“CUDA ARCH”宏根据计算能力区分不同的代码路径。它只为设备代码定义。例如,当使用-arch=compute_35编译时,__CUDA_ARCH_等于350。

使用驱动程序API的应用程序必须编译代码以分离文件,并在运行时显式加载和执行最合适的文件。

Volta架构引入了独立的线程调度,它改变了GPU上线程的调度方式。对于依赖于以前架构中SIMT调度的特定行为的代码,独立的线程调度可能会改变参与线程的集合,从而导致错误的结果。为了帮助迁移,同时实现独立线程调度中详述的纠正操作,Volta开发人员可以选择使用编译器选项-arch=compute_60 -code=sm_70来执行Pascal的线程调度。

nvcc用户手册列出了-arch、-code和-gencode编译器选项的各种简写。例如,

-arch=sm_35 is a shorthand for -arch=compute_35-code=compute_35,sm_35 (which is the same as -gencodearch=compute_35,code=\'compute_35,sm_35\').

1.5、C/C++兼容性

编译器的前端编译器根据C++语法规则处理CUDA源文件。但是,对于C/C++语言描述的设备代码,只支持C++的一个子集。

1.6. 64位兼容性

64位版本的nvcc以64位模式编译设备代码(即指针为64位)。只有在64位模式下编译的主机代码才支持在64位模式下编译的设备代码。

类似地,32位版本的nvcc以32位模式编译设备代码,而32位模式编译的设备代码仅支持以32位模式编译的主机代码。

32位版本的nvcc还可以使用-m64编译器选项以64位模式编译设备代码。

64位版本的nvcc可以使用-m32编译器选项以32位模式编译设备代码。

CUDA C编程接口技术分析的更多相关文章

  1. CUDA C++编程接口:编译

    CUDA C++编程接口:编译 一.概述 CUDA C++为熟悉C++编程语言的用户提供了一个简单的路径,以方便地编写程序以执行该设备. 它由一组最小的扩展到C++语言和运行库. 在编程模型中引入了核 ...

  2. http_load安装与测试参数分析 - 追求自由自在的编程 - ITeye技术网站

    http_load安装与测试参数分析 - 追求自由自在的编程 - ITeye技术网站 http_load -p 50 -s 120 urls

  3. 横向技术分析C#、C++和Java优劣

    转自横向技术分析C#.C++和Java优劣 C#诞生之日起,关于C#与Java之间的论战便此起彼伏,至今不辍.抛却Microsoft与Sun之间的恩怨与口角,客观地从技术上讲,C#与Java都是对传统 ...

  4. AOP技术分析

    AOP的概述(http://www.cnblogs.com/lxp503238/p/6837653.html)        1. 什么是AOP的技术?        * 在软件业,AOP为Aspec ...

  5. Turing渲染着色器网格技术分析

    Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...

  6. 基于VC的ACM音频编程接口压缩Wave音频(一)

    (一)概述 音频数据一般都具有较高的采样率,经过压缩的原始数据才具有实用价值,否则不仅要占用大量存储空间而且在播放或进行网络传输时效率也是非常低下的,所以音频数字压缩编码在多媒体应用中有着广泛而又重要 ...

  7. 【OpenCV & CUDA】OpenCV和Cuda结合编程

    一.利用OpenCV中提供的GPU模块 目前,OpenCV中已提供了许多GPU函数,直接使用OpenCV提供的GPU模块,可以完成大部分图像处理的加速操作. 基本使用方法,请参考:http://www ...

  8. iOS直播的技术分析与实现

    HTTP Live Streaming直播(iOS直播)技术分析与实现 发布于:2014-05-28 13:30阅读数:12004 HTTP Live Streaming直播(iOS直播)技术分析与实 ...

  9. Java8内置的函数式编程接口应用场景和方式

    首先,我们先定义一个函数式编程接口 @FunctionalInterface public interface BooleanFunctionalInterface<T> { boolea ...

随机推荐

  1. Python中对序列数据的汇总(collections模块)

    目录 Counter most_common 对于序列如字符串str.列表list和tuple可以统计里面数据出现的次数.我们使用的是 collections 模块. collections模块的常用 ...

  2. Python 爬虫与HTTP协议简介

    爬虫的实际例子: 搜索引擎(百度.谷歌.360搜索等). 伯乐在线. 惠惠购物助手. 数据分析与研究(数据冰山知乎专栏). 抢票软件等. 什么是网络爬虫: 通俗理解:爬虫是一个模拟人类请求网站行为的程 ...

  3. (8)MySQL进阶篇SQL优化(InnoDB锁-共享锁、排他锁与意向锁)

    1.锁的分类 锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制.之前MyISAM锁章节已经讲过锁分类,而InnoDB锁按照粒度分为锁定整个表的表级锁(table-level l ...

  4. Day009 类和对象的创建

    类和对象的关系 类是一种抽象的数据结构,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物 动物.植物.手机.电脑 Person类.Pet类.Car类等,这些都是用来描述/定义某一类具体的 ...

  5. 简单使用高德地图开放平台API

    需求说明 输入经纬度,得到城市名 挑选API 使用高德逆地理编码API,点击查看文档 demo <?php /** * 根据输入的经纬度返回城市名称 * @param $longitude 终点 ...

  6. Docker 部署net5程序

    1.前言 本文讲述使用docker容器部署.net5项目.实现跨平台. 部署环境:docker 容器.liunx系统.这里采用VmWare虚拟机.并采用MobaXterm工具实现终端连接linux系统 ...

  7. OO课程仓库部署使用GitLab CI

    转自我的个人博客http://mistariano.com/blog/9 1. 服务器上安装 gitlab-runner 参考博客https://blog.csdn.net/qq_40699305/a ...

  8. mac SSH私钥取消密码(passphrase)

    取消私钥中的密码: 1.使用openssl命令去掉私钥的密码openssl rsa -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa_new 2.备份旧私钥mv ~/.ssh/ ...

  9. [c++] 如何流畅地读写代码

    代码不同于普通文字,阅读时注意两方面: 符号含义:相同符号,上下文不同时含义也不同,如*和& 阅读顺序:不总是按从左往右顺序阅读的,有时要倒着读或者跳着读逻辑才通顺 适当省略:有些内容虽然写了 ...

  10. GCC链接时库顺序问题

    GCC或G++在编译链接时,如果命令行中含有库,则要特别注意了.根据<C专家编程>5.3节中的提示,GCC在链接时对命令行时的处理顺序是从左到右.证据是GCC的MAN: -l librar ...