CUDA的软件堆栈由以下三层构成:CUDA Library、CUDA runtime API、CUDA driver API,如图所示,CUDA的核心是CUDA C语言,它包含对C语言的最小扩展集和一个运行时库,使用这些扩展和运行时库的源文件必须通过nvcc编译器进行编译。

CUDA C语言编译得到的只是GPU端代码,而要管理分配GPU资源,在GPU上分配显存并启动内核函数,就必须借助CUDA运行时的API(runtime API)或者CUDA驱动API(driver API)来实现。在一个程序中只能使用CUDA运行时API与CUDA驱动API中的一种,不能混和使用。

一、CUDA C语言

CUDA C语言为程序提供了一种用C语言编写设备端代码的编程方式,包括对C的一些必要扩展和一个运行时库。CUDA对C的扩展主要包括以下几个方面

1.引入了函数类型限符。用来规定函数是在host还是在device上执行,以及这个函数是从host调用还是从device调用。这些限定符有:__device__,__host__,__global__.

2.引入了变量类型限定符。用来规定变量被存储在哪一类存储器上。传统的在CPU上运行的程序,编译器能自动决定将变量存储在CPU的寄存器还是内存中,在CUDA编程模型中,一共抽象出来多棕8种不同的存储器。为了区分各种存储器,必须引入一些限定符,包括:__device__,__shared__和__constant__。注意,此处的__device__与上节中的__device__限定符的含义不同。

3.引入了内置变量类型。如char4,ushort3,double2,dim3等,它们是由基本的整型可浮点型构成的矢量类型,通过x,y,z,w访问每一个分量,在设备端代码中各矢量类型有不同的对齐要求。

4.引入了4个内建变量。blockIdx和threadIdx用于索引线程块和线程,gridDim和blockDim用于描述线程网格和线程块的维度。warpZize用于查询warp中的线程数量。

5.引入了<<< >>>运算符。用于指定线程网格和线程维度,传递执行参数。

6.引入了一些函灵敏:memory fence函数,同步函数,数学函数,纹理函数,测时函数,原子函数,warp vote函数。

以上扩展均有一些限制,如果违背了这些限制,nvcc将给出错误或警告信息,但有时也不会报错,程序无法运行。

二、nvcc编译器

nvcc编译器根据配置编译CUDA C代码,可以生成三种不同的输出:PTX,CUDA二进制序列和标准C。nvcc是一种编译驱动。通过命令行选项,nvcc可以在编译的不同阶段启动不同的工具完成编译工作。

nvcc工作的基本流程是:首先通过CUDAfe分离源文件中的主机端和设备端代码,然后再调用不同的编译器分别编译。设备端代码由nvcc编译成ptx代码或者二进制代码;主机端代码则将以C文件形式输出,由其他主性能编译器,旧ICC,GCC或者其他合适的高性能编译器等进行编译。不过,也可以直接在编译的最后阶段,将主机端代码交给其他编译器生成.obj或者.o文件。在编译时,可以将设备端代码链接到所生成的主机端代码,将其中的cubin对象作为全局初始化数据数组包含进来。此时,内核执行配置也要被转换为CUDA运行启动代码,以加载和启动编译后的内核函数。使用CUDA驱动API时,可以单独执行ptx代码或者cubin对象,而忽略nvcc编译得到的主机端代码。

编译器前端按照C++语法规则对CUDA源文件进行处理。CUDA主机端代码可以支持完整的C++语法,而设备端代码则不能完全支持。

内核函数可能通过PTX编写,但通常还是通过CUDA C一类的高级语言进行编写。PTX或CUDA C语言编写的内核函数都必须通过nvcc编译器编译成二进制代码。一部分PTX指令只能在拥有较高计算能力的硬件上执行,比如对全局存储器的32bit原子操作指令就只有计算能力1.1以上的硬件才能支持,双精度计算只有计算能力1.3以上的硬件才能支持。nvcc通过编译选项来指定要输出的PTX代码的计算能力。因此,在需要双精度计算时,就必须加上-arch sm_13(或者更高计算能力)编译选项才能正常运行,否则双精度计算将被编译为间精度的计算。

三、运行时API与驱动API

CUDA runtime API和CUDA driver API提供了实现设备管理(Device management),上下文管理(Context management),存储器管理费用(Memory Control),代码块管理 (Code Module management),执行控制(Excution Control),纹理索引管理(Texture Reference management)与OpenGL和Direct3D的互操作性(Interoperity with OpenGL and Direct3D)的应用程序接口。

CUDA runtime API在CUDA driver API 的基础上进行了封装,隐藏了一些实现细节,编程更加方便,代码更加简洁。CUDA runtime API被打包放在CUDAArt包里,其中的函数都有CUDA 前缀。CUDA运行时没有专门的初始化函数,它将在第一次调用函数时自动完成初始化。对使用运行时函数的CUDA程序测试时要避免将这段初始化的时间计入。CUDA runtime API的编程较为简洁,通常都会用这种API进行开发。

CUDA driver API是一种基于句柄的底层接口(式多对象通过句柄被引用),可以加载二进制或汇编形式的内核函数模块,指定参数,并启动计算。CUDA driver API的编程复杂,但有时能通过直接操作硬件的执行实行一些更加复杂的功能键,或者获得更高的性能。由于它使用的设备端代码是二进制或者汇编代码,因此可以在各种语言中调用。CUDA driver API被放在nvCUDA包里,所有函数前缀为cu。

四、CUDA函数库

目前CUDA中有CUFFT,CUBLAS和CUDPP三个函数库,提供了简单高效的常用函数。未来,CUDA中还会提供视频编解码与图像处理库等,如CUVID,进一步扩充功能。CUFFT是利用GPU进行傅立叶变换的函数库,提供了与广泛使用的FFTW库相似的接口。不同的是FFTW操作的数据存储在内在中,而CUFFT操作的数据存储在显存,不能直接相互取代,必须加入显存与内存之间的数据交换,进行封装后才能替代FFTW库。CUBLAS库是一个基本的矩阵与向量运算库,提供了与BLAS相似的接口,可以用于简单的矩阵计算,也可以作为基础构建更加复杂的函数包,如LAPACK等,CUBLAS操作的数据也存储在显存中,同样需要封装后才能替代BLAS中的函数。CUDPP为提供了很多基本的常州用的并行操作灵敏,如排序、搜索等,可以作为基本组件快速地搭建出并行计算程序。调用上述函数库使得程序员无须按照硬件特性设计复杂的算法就能获得很高的性能,大大缩短开发时间;缺点是上述函数库灵活性稍差,并且有可能造成多余的存储器访问。

CUDA的软件体系的更多相关文章

  1. 全球最低功耗蓝牙单芯片DA14580的软件体系 -层次架构和BLE消息事件处理过程

    在作者之前发表的<全球最低功耗蓝牙单芯片DA14580的系统架构和应用开发框架分析>.<全球最低功耗蓝牙单芯片DA14580的硬件架构和低功耗>.<全球最低功耗蓝牙单芯片 ...

  2. 全球最低功耗蓝牙单芯片DA14580的软件体系 -RW内核和消息处理机制

    上一篇文章<蓝牙单芯片DA14580的硬件架构和低功耗>阐述了DA14580的硬件架构和低功耗的工作原理.本文文章阐述该平台的软件体系,并着重分析消息事件的处理机制. 一.DA14580S ...

  3. 解读IEEE 7417的软件体系架构描述的概念模型

    本文将解读标准IEEE Std 1471-2000(密集型软件的体系结构描述推荐实施规程)的概念模型图部分,从中一窥作为软件架构师的进行架构设计的思考角度与策略.如果我们把世界当做一场游戏,现在要玩的 ...

  4. Atitit 软件体系的进化,是否需要一个处理中心

    Atitit 软件体系的进化,是否需要一个处理中心 1.1. 进化树上是没有主干的..1 1.2. ,软件进化的行为1::主要就是给新的应用编写新的程序.1 1.3. ,软件进化的行为2::软件的维护 ...

  5. 软件体系架构之ssh框架阅读笔记

    首先我们要了解一下什么是ssh框架? SSH是 struts+spring+hibernate的一个集成框架,是目前比较流行的一种Web应用程序开源框架. ssh框架系统从职责上分为四层:web层 业 ...

  6. CUDA基础介绍

    一.GPU简介 1985年8月20日ATi公司成立,同年10月ATi使用ASIC技术开发出了第一款图形芯片和图形卡,1992年4月ATi发布了Mach32图形卡集成了图形加速功能,1998年4月ATi ...

  7. CUDA vs GPGPU

    http://www.kuqin.com/hardware/20080830/15726.html 一 在硬件和软件之间选择     “计算机软件和硬件的逻辑等价性”是计算机组成原理中一个非常重要的理 ...

  8. 软件产品案例分析----K米app

    第一部分 调研.评测 1.1评测 1.1.1 第一次上手体验 1.1.2 bug 1.1.2.1 bug定义 1.1.2.2 栗子 1.1.2.2.1 A级 1.1.2.2.2 B级 1.1.2.2. ...

  9. CUDA程序设计(一)

    为什么需要GPU 几年前我启动并主导了一个项目,当时还在谷歌,这个项目叫谷歌大脑.该项目利用谷歌的计算基础设施来构建神经网络. 规模大概比之前的神经网络扩大了一百倍,我们的方法是用约一千台电脑.这确实 ...

随机推荐

  1. 通过jQuery实现AJAX

    通过jQuery实现AJAX > 使用get和getJSON都会有缓存问题,并且使用get方法不能传送较多的数据. 问题: 在IE浏览器中,get请求使用ajax存在缓存问题,会使用上一次请求的 ...

  2. Java: 面向对象程序设计(下)

    1. 类的继承 继承的意义: 当一个类A继承了一个已存在的类B后,类A就用于了类B所有的非private的属性和方法,但同时类A还可以根据需要,添加新的方法和属性. 在Java语言中,一个类可以拥有多 ...

  3. ELK系列(4) - Elasticsearch cannot write xcontent for unknown value of type class java.math.BigDecimal

    问题与分析 在使用Elasticsearch进行index数据时,发现报错如下: java.lang.IllegalArgumentException: cannot write xcontent f ...

  4. 原生JS轮播-各种效果的极简实现

    寒假持续摸鱼中~此为老早以前博客的重写,当时还是分开写的,这里汇总重写,正好复习一遍~ 春招我来了! 所有有意思的,一股脑先扔进收藏,然后再也不看哈哈,真是糟糕. 今日事,今日毕,说起来容易. 当时竟 ...

  5. DateTime.MinValue和MaxValue引发的异常

    转载: http://www.cnblogs.com/lori/p/3186807.html 问题描述: SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/3 ...

  6. Django---登录(含随机生成图片验证码)、注册示例讲解

    登录(验证码).注册功能具体代码 # urls.py from django.contrib import admin from django.urls import path from app01 ...

  7. sql 更新 批量更新 更新得到主键

    import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.c ...

  8. 非局部均值去噪(NL-means)

    非局部均值(NL-means)是近年来提出的一项新型的去噪技术.该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持图像的细节特征.基本思想是:当前像素的估计值由图像中与它具有相似邻域结构的 ...

  9. ElasticSearch 全文检索— ElasticSearch 安装部署

    ElasticSearch 规划-集群规划 ElasticSearch 规划-集群规划 ElasticSearch 规划-用户规划 ElasticSearch 规划-目录规划 ElasticSearc ...

  10. Sqoop环境安装

    环境下载 首先将下载的 sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz放到 /usr/hadoop/目录下(该目录可以自定义,一般为Hadoop集群安装目录),然 ...