CUDA C++编程接口:编译

一.概述

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

它由一组最小的扩展到C++语言和运行库。

在编程模型中引入了核心语言扩展。它们允许程序员定义内核作为C++函数,并使用一些新的语法来指定每次调用函数时的网格和块维数。所有扩展的完整描述可以在C++语言扩展中找到。任何包含这些扩展名的源文件都必须使用nvcc编译,如使用nvcc编译中所述。在CUDA运行时中引入了运行时。它提供了在主机上执行的C和C++函数,分配和释放设备存储器,在主机内存和设备内存之间传输数据,管理多个设备的系统等。运行时的完整描述可以在CUDA参考手册中找到。

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

二.用NVCC编译

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

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

2.1.编译工作流

2.1.1. 脱机编译

用nvcc编译的源文件可以包括主机代码(即,在主机上执行的代码)和设备代码(即,在设备上执行的代码)的混合。nvcc的基本工作流程是将设备代码与主机代码分离,将设备代码编译为汇编形式(PTX代码)和/或二进制形式(cubin对象),并通过用必要的CUDA运行时函数调用替换内核中引入的语法(并在执行配置中详细描述)来修改宿主代码,以便从PTX代码和/或cubin对象加载和启动每个编译的内核。

将修改后的主机代码输出为C++代码,该代码将被另一个工具编译或直接作为对象代码,通过NVCC在最后编译阶段调用宿主编译器。

应用程序,链接到已编译的主机代码(这是最常见的情况),或者忽略修改后的主机代码(如果有的话),并使用CUDA驱动程序API(请参阅驱动程序API)来加载和执行PTX代码或cubin对象。

2.1.2.即时编译

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

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

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

作为使用NVCC来编译CUDA C++设备代码的替代方案,NVRTC可以用于在运行时编译CUDA C++设备代码到PTX。NVRTC是CUDA C++的运行时编译库;NVRTC用户指南中可以找到更多信息。

2.2.二进制兼容性

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

注意:仅桌面支持二进制兼容性。Tegra不支持此功能。桌面和Tegra之间的二进制兼容性也不受支持。

2.3.PTX兼容性

某些PTX指令仅在具有更高计算能力的设备上受支持。例如,Warp Shuffle函数仅在计算能力为3.0及以上的设备上受支持。-ARCH编译器选项指定编译C++到PTX代码时所假定的计算能力。例如,包含warp shuffle的代码必须使用-arch=compute_(或更高版本)编译。为某些特定计算能力生成的PTX代码始终可以编译为具有更大或同等计算能力的二进制代码。请注意,从早期PTX版本编译的二进制文件可能无法使用某些硬件功能。例如,从为计算能力6.0(Pascal)生成的PTX编译的计算能力7.0(Volta)的二进制目标设备将不会使用张量核心指令,因为这些指令在Pascal上不可用。因此,最终的二进制文件的性能可能比使用最新版本的PTX生成的二进制文件的性能差。

2.4.应用程序兼容性

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

在NUCC用户手册中详细说明了在CUDA C++应用程序中嵌入的PTX和二进制代码是由-ARCH和-CODER编译器选项或-GEnCODE编译器选项控制的。例如,

nvcc x.cu

-gencode arch=compute_35,code=sm_35

-gencode arch=compute_50,code=sm_50

-gencode arch=compute_60,code=\'compute_60,sm_60\'

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

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

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及更高的设备才支持这种操作。根据计算能力,可以使用uda_uarch_uu宏来区分不同的代码路径。它只为设备代码定义。例如,当使用-arch=compute_35编译时,_uucuda_uarch_u等于350。

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

Volta架构引入了独立的线程调度,它改变了GPU上线程的调度方式。对于依赖于以前架构中SIMT调度的特定行为的代码,独立的线程调度可能会改变参与线程的集合,从而导致错误的结果。为了帮助迁移,同时实现独立线程调度中详述的纠正操作,Volta开发人员可以选择使用编译器选项combination-arch=compute_-code=sm_来执行Pascal的线程调度。nvcc用户手册列出了-arch、-code和-gencode编译器选项的各种缩写。例如,-arch=sm_35是-arch=compute_35-code=compute_35,sm_35的缩写(与-gencodearch=compute_35,code=\'compute_35,sm_35'相同)。

2.5.  C++兼容性

编译器的前端根据C++语法规则处理CUDA源文件。主机代码支持完全C++。但是,C++语言支持中只支持一个C++子集。

2.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语言的最小扩展集和运行库组成. 核心语言扩展已经引入:cuda c ...

  2. mpi和cuda混合编程的正确编译

    针对大数据的计算,很多程序通过搭建mpi集群进行加速,并取得了很好的效果.算法内部的加速,当前的并行化趋势是利用GPU显卡进行算法加速.针对并行性非常好的算法,GPU加速效果将远大于集群带来的加速效果 ...

  3. CUDA C++编程手册(总论)

    CUDA C++编程手册(总论) CUDA C++ Programming Guide The programming guide to the CUDA model and interface. C ...

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

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

  5. CUDA 标准编程模式

    前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...

  6. 第三篇:CUDA 标准编程模式

    前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...

  7. OCCI编程接口介绍

    OCCI简介 Oracle® C++ Call Interface (OCCI) 是一套应用程序编程接口,它允许C++程序与一个或者多个Oracle数据库进行交互.OCCI给予你强大的数据库操作能力, ...

  8. 摄像头驱动的使能配置、V4L2编程接口的设计应用

    摄像头采集子系统 一.摄像头驱动的使能配置 摄像头软件驱动构架 摄像头采集系统由上图所示,硬件(摄像头) -> 驱动(Linux内核配置中,选择支持V4L2的驱动选项) -> V4L2接口 ...

  9. Java 虚拟机编程接口JVMIT

    JVMTI(JVM Tool Interface)是 Java 虚拟机所提供的 native 编程接口,是 JVMPI(Java Virtual Machine Profiler Interface) ...

随机推荐

  1. 阿里云《nginx服务器配置SSL证书》 配置参数

    server { listen 443; server_name demo.shengruijt25.com; ssl on; root html; index index.html index.ht ...

  2. 安全之路 —— 无DLL文件实现远程进程注入

    简介 在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着实是怪麻烦的,那 ...

  3. 分布式事务与Seate框架(1)——分布式事务理论

    前言 虽然在实际工作中,由于公司与项目规模限制,实际上所谓的微服务分布式事务都不会涉及,更别提单独部署构建Seata集群.但是作为需要不断向前看的我,还是有必要记录下相关的分布式事务理论与Seate框 ...

  4. 【JavaScript】Leetcode每日一题-矩形区域不超过K的最大值和

    [JavaScript]Leetcode每日一题-矩形区域不超过K的最大值和 [题目描述] 给你一个 m x n 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大 ...

  5. 03.28,周六,12:00-17:00,ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016正式赛。

    A. Majestic 10 题意:三个数均大于10则输出"triple-double",如果两个数大于10则输出"double-double",如果一个大于1 ...

  6. 80行代码教你写一个Webpack插件并发布到npm

    1. 前言 最近在学习 Webpack 相关的原理,以前只知道 Webpack 的配置方法,但并不知道其内部流程,经过一轮的学习,感觉获益良多,为了巩固学习的内容,我决定尝试自己动手写一个插件. 这个 ...

  7. 2.HTML案例二 头条页面

    4 HTML案例-头条页面 4.1 案例效果 4.2 案例分析 4.2.1 div布局的进阶 想要将div布局成案例效果,首先需要对多个div进行区分,再分别设置每一个div自身的效果. 1)div的 ...

  8. 解决nohup: 忽略输入并把输出追加到"nohup.out"或者nohup: 忽略输入重定向错误到标准输出端

    nohup启动脚本的时候,没有指定输出路径,默认使用当前目录的nohup.out 例如下面这句就是默认使用nohup.out作为输出文件: nohup script.sh & 改成下面的,则/ ...

  9. HTML中的全局属性

    一.全局属性和局部属性 每种元素都有自己规定的属性,这种属性成为局部属性.还有另外一种属性,他可以用来配置所有元素的共有行为,这种属性成为称为全局属性.全局属性可以用在任何一个元素身上,但是不一定会带 ...

  10. shell 获取MySQL查询结果并处理

    主要应用到shell for循环 定义数据库连接信息 HOST_NAME='127.0.0.1' DB_PORT='3306' DB_NAME='数据库名' USER_NAME='root' PASS ...