CUDA学习

article/2025/9/7 4:34:00

    想想学习CUDA的时间也应该有十来天了,也该是做一个小总结了,说说我理解的CUDA,它到底是什么东西?

     其实说到CUDA,还真的没几个人知道,说实话,我也听说不久,主要因为它2007年才刚发布,也是这几年才刚兴起,国内那就更慢了。

    CUDA它中文的名字是统一计算设备架构,CUDA是一种将GPU作为数据并行计算设备,听到并行这个名称,我相信很多热爱计算机的朋友就特别兴奋,因为这意味着速度会很快,确实,CUDA就是为了提高计算速度的一个计算机架构。

    要理解CUDA,就先理解一个基本概念:GPU是图形处理单元 (Graphic Processing Unit) 的简称,最初主要用于图形渲染。 由于GPU 拥有比CPU 更强的计算能力,很早就有人想到将GPU 应用到通用计算上,这就是GPGPU,所谓GPGPU 是指直接使用了图形学的API,将任务映射成纹理的渲染过程,使用汇编或者高级着色器语言CgHLSL 等编写程序,然后通过图形学API 执行(Direct3DOpenGL),这样的开发不仅难度较大,而且难以优化,对开发人员的要求非常高,因此,传统的GPGPU 计算并没有广泛应用。  2007 月,NVIDIA 公司推出了CUDA (Compute Unified Device Architecture) , CUDA 不需要借助图形学API,而是采用了类语言(CUDA C)进行开发。

   由于CUDA使用的是类C语言(CUDA C)语言开发,因此对于对C语言有所理解的程序员都可以开发,因此它得到很大的广泛应用。

    其实CUDA有很多用途,因为它有并行计算的能力,因此只要有并行计算的地方就可以用它,就像在OpenGL或者是D3D中都可以用CUDA来进行计算的加速,众所周知,在图形学中很多操作都是用矩阵来进行运算,所以在OpenGL中就可以加入CUDA的架构,其实CUDA两个是独立的架构,用CUDA只是用来并行运算,当把数据处理完了之后就要返回到OpenGL中进行渲染,当然CUDA的用途不仅如此,它还有更高级的用途。 

   今天我就来讲讲有关于CUDA的编程模型:

    1.主机和设备

       CUDA 编程模型将CPU作为主机(Host),GPU作为协处理器或者设备(Device),在一个系统中可以存在一个主机和若干个设备。

             在这个模型中,CPUCPU协同工作,各司其职。CPU负责进行逻辑性强的事物处理和串行计算,GPU则专注于执行高度线程化的并行处理任务。CPUGPU各自拥有相互独立的存储器地址空间:主机端的内存和设备端的显存。

            一旦确定了程序的并行部分,就可以考虑把这部分计算工作交给GPU

            能够使用GPU计算的程序必须具有以下特点:需要处理的数据量比较大,数据以数组或矩阵形式有序存储,并且对这些数据要进行的处理方式基本相同,各个数据之间的依赖性或者说耦合很小,需要复杂数据结构的计算如树,图等,则不适用于使用GPU进行计算。找到程序中满足这些要求的部分后,就能将该部分程序移植GPU上。运行在GPU上的程序被称为内核(Kernel)。内核并不是完整的程序,只是整个程序中的一个可以使用数据并行处理的步骤。一个完整的程序由若干个内核函数以及CPU上的串行处理共同组成。一个完整的程序的计算流程如下所示:

 

 

 

2. 线程结构

       内核以线程网格(Grid)的形式组织,每个线程网格由若干个线程块(block)组成,而每个线程块又由若干个线程(thread)组成。实质上,内核(kernel)是以block为单位执行的,CUDA引入grid只是用来表示一系列可以被并行执行的block的集合,各block的集合。各block是并行执行的,block间无法通信,也没有执行顺序。

 

           目前一个内核(kernel)函数中只有一个grid,而未来的支持DX11的硬件采用MIMD(多指令多数据)结构,允许一个kernel中存在多个不同的grid。(目前是使用SIMT(单指令多线程)。

           为简便起见,threadIdx是一个有3个组件的向量,所以线程可以使用一维,二维,三维索引标识,形成一维,二维,三维的线程块。这提供了一种自然的方式来调用作用在域内元素上的计算,如向量,矩阵,体元(volume)(译者注:目前还没见过使用三维的,原因可能在于网格不支持三维)。

            线程索引线程ID直接相关:对于一维的块,它们相同;对于二维长度为(Dx,Dy)的块,线程索引为(x,y)的线程ID(x+yDx);对于三维长度为(Dx,Dy,Dz)的块,索引为(x,y,z)的线程ID为(x+yDx+zDxDy)

实例代码:

 

// Kernel definition 
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N]){ 
int i = threadIdx.x; 
int j = threadIdx.y; 
C[i][j] = A[i][j] + B[i][j]; 
} 
//host code
int main() { 
... 
// Kernel invocation with one block of N * N * 1 threads 
int numBlocks = 1; 
dim3 threadsPerBlock(N, N); 
MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C); 
} 

     今天我讲讲CUDA所用到的编译器nvcc:

 —nvcc编译器根据配置编译CUDA C代码,可以生成三种不同的输出:PTXCUDA二进制序列和标准C

—nvcc可编译同时包含主机代码(在主机上执行的代码)和设备代码(在设备上执行的代码)的源文件。nvcc的基本流程包括分离主机和设备代码并将设备代码编译成汇编形式(PTX)或/和二进制形式(cubin对象)。生成的主机代码要么被输出为C代码供其它工具编译,要么在编译的最后阶段被nvcc调用主机编译器输出为目标代码。
—应用在运行时装载的任何PTX代码被设备驱动进一步编译成二进制代码。这称为即时编译。
—PTX类似于汇编语言,是为动态编译器JIT(即时编译)设计的输入指令序列。这样虽然不同的显卡使用的机器语言不同,JIT却可以运行同样的PTX。这样做使PTX成为一个稳定的接口,带来了很多好处:后向兼容性,更长的寿命,更好的可扩展性和更高的性能,但在一定程度上也限制了工程上的自由发挥。这种技术保证了兼容性,但也使新一代的产品必须拥有上代产品的所有能力,这样才能让今天的PTX代码在未来的系统仍然可以运行。 虽然PTX和JIT编译器提供了很高的性能,但也不是在所有场合都适用。某些独立的开发商倾向于牺牲性能,以获得更好的可确定性和可验证性。JIT编译器的输出会因为目标硬件和一些其他因素发生变化。
—编译的大概流程如下图:

一.纹理存储器介绍

纹理存储器(texture memory)是一种只读存储器,由GPU用于纹理渲染的的图形专用单元发展而来,因此也提供了一些特殊功能。纹理存储器中的数据位于显存,但可以通过纹理缓存加速读取。在纹理存储器中可以绑定的数据比在常量存储器可以声明的64K大很多,并且支持一维、二维或者三维纹理。在通用计算中,纹理存储器十分适合用于实现图像处理或查找表,并且对数据量较大时的随机数据访问或者非对齐访问也有良好的加速效果

纹理缓存有两个作用。首先,纹理缓存中的数据可以被重复利用,当一次访问需要的数据已经存在于纹理缓存中时,就可以避免对显存进行读取。数据重用过滤了一部分对显存的访问,节约了带宽,也不必按照显存对齐的要求读取。第二,纹理缓存可以缓存拾取坐标附近几个像元的数据,可以实现滤波模式,也能提高具有一定局部性的访问的效率。

纹理存储器是只读的,不需要关心缓存数据一致性问题。这意味着如果更改了绑定到纹理存储器的数据,纹理缓存中的数据可能并没有被更新,此时通过纹理拾取得到的数据可能是错误的。因此,在每次修改了绑定到纹理的数据以后,都需要对纹理进行重新绑定。由于不能从设备端修改CUDA数组,因此只有在对绑定到纹理的线性内存进行修改时才需要注意这一点。

二.纹理存储器的使用步骤:

1.       声明CUDA数组,分配空间

声明CUDA数组之前,必须先以结构体channelDesc描述CUDA数组中的数据类型。

struct cudaChannelFormatDesc {
     
int x, y, z, w;
     enum cudaChannelFormatKind f;
};

   cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKindFloat);

    cudaArray* cu_array;

    cutilSafeCall( cudaMallocArray( &cu_array, &channelDesc, width, height ));                       //为cu_array开辟空间

cutilSafeCall( cudaMemcpyToArray( cu_array, 0, 0, h_data, size, cudaMemcpyHostToDevice));  //复制到设备端的数组

2.       声明纹理参照系

// declare texture reference for 2D float texture        声明纹理参照系

texture<float, 2, cudaReadModeElementTypetex;

3.       设置运行时纹理参照系属性

tex.addressMode[0] = cudaAddressModeWrap;        //采用循环模式

tex.addressMode[1] = cudaAddressModeWrap;        //说明寻址模式

tex.filterMode = cudaFilterModeLinear;           //设置纹理的滤泼模式

    tex.normalized = true;    // access with normalized texture coordinates设置是否对纹理坐标进行归一化

4.       纹理绑定

// Bind the array to the texture             //纹理绑定

    cutilSafeCallcudaBindTextureToArraytexcu_arraychannelDesc));

5.       纹理拾取

g_odata[y*width + x] = tex2D(textutv);       //纹理拾取


http://chatgpt.dhexx.cn/article/rZdDPm9d.shtml

相关文章

CUDA简介

CUDA简介 CUDA是什么 CUDA&#xff0c;Compute Unified Device Architecture的简称&#xff0c;是由NVIDIA公司创立的基于他们公司生产的图形处理器GPUs&#xff08;Graphics Processing Units,可以通俗的理解为显卡&#xff09;的一个并行计算平台和编程模型。 通过CUDA&#…

CUDA是什么-CUDA简介

在大家开始深度学习时&#xff0c;几乎所有的入门教程都会提到CUDA这个词。那么什么是CUDA&#xff1f;她和我们进行深度学习的环境部署等有什么关系&#xff1f;通过查阅资料&#xff0c;我整理了这份简洁版CUDA入门文档&#xff0c;希望能帮助大家用最快的时间尽可能清晰的了…

java队列和栈 共同_java 栈和队列的模拟--java

栈的定义&#xff1a;栈是一种特殊的表这种表只在表头进行插入和删除操作。因此&#xff0c;表头对于栈来说具有特殊的意义&#xff0c;称为栈顶。相应地&#xff0c;表尾称为栈底。不含任何元素的栈称为空栈。 栈的逻辑结构&#xff1a;假设一个栈S中的元素为an,an-1,..,a1&am…

栈和队列学习总结

一、栈 1、特点及应用 先进后出。(如果会和队列先进先出记混的话,就记场景吧:弹栈弹栈,就是把最上面的最新进来的弹出去;而队列就像我们火车站排队检票出站一样,谁排在前面谁就先出去。) 应用的话,其实我们经常接触呀。比如Undo操作(就是撤销操作)就是使用的栈的思想…

栈和队列的共同点和不同点

堆栈都是一种数据项按序排列的数据结构&#xff0c;只能在一端(称为栈顶(top))对数据项进行插入和删除。 要点&#xff1a;堆&#xff1a;顺序随意 栈&#xff1a;后进先出(Last-In/First-Out) 堆 堆&#xff1a;什么是堆&#xff1f;又该怎么理解呢&#xff1f; ①堆通常是一…

栈和队列实现和实例分析

目录 前言栈队列实例分析结语 前言 本篇文章主要讲述数据结构中栈和队列的实现&#xff0c;以及相关实例分析。 栈 注意本文所讲述的栈是数据结构的一种&#xff0c;并不是内存划区中的栈区&#xff0c;但是这两者有相似之处&#xff0c;即&#xff1a;存储数据时满足数据先…

栈和队列的共同处和不同处

共同处 栈和队列的共同处是&#xff1a;它们都是由几个数据特性相同的元素组成的有限序列&#xff0c;也就是所谓的线性表。 不同处 队列 队列&#xff08;queue&#xff09;是限定仅在表的一端插入元素、在另一端删除元素的线性表。 在队列中&#xff0c;允许插入的一端被…

索引的优缺点以及索引的设计原则

索引概述 索引&#xff08;index&#xff09; 是帮助 MySQL 高效获取数据的数据结构&#xff08;有序&#xff09;。 在数据之外&#xff0c;数据库系统还维护者满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0…

SQL数据库之索引优缺点

SQL数据库之索引使用原则及利弊 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。 优点 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。 可以大大加快数据的检索速度&#xff0c;这也是创建…

Oracle索引的建立及优缺点

在看公司建表语句时发现了这样一段代码 本着学习的态度面向百度&#xff1a;&#xff1a;&#xff1a;&#xff1a;&#xff1a; 原来这是Oracle的索引 Oracle的索引说明 1&#xff09;索引是数据库对象之一&#xff0c;用于加快数据的检索&#xff0c;类似于书籍的索引。在…

MySQL索引的优缺点

MySQL 中的索引简介 1、索引的优点 为什么要创建索引&#xff1f;这是因为&#xff0c;创建索引可以大大提高系统的查询性能。 第一、通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。 第二、可以大大加快数据的检索速度&#xff0c;这也是创建索引的最…

MySQL索引的使用知识有哪些?

面试造火箭&#xff0c;工作拧螺丝&#xff0c;虽然工作时我们都在使用基本的 sql&#xff0c;但是不好意思&#xff0c;面试 90% 都在问原理&#xff0c;例如索引&#xff0c;锁&#xff0c;日志&#xff0c;引擎啊等等。 在关系数据库中&#xff0c;索引是一种单独的、物理的…

索引的数据结构与优缺点

1、索引的数据结构 什么是索引&#xff1f; 索引就是mysql为了提高查询数据的一种数据结构。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法 的数据结构&#xff0c;这些数据结构以某种方式引用(指向)数据&#xff0c;这样就可以在这些数据结构上实现高级查找 算法…

Oracle 数据库:ORA-12541: TNS: 无监听程序 的解决办法

路径下D:\app\ou\product\11.2.0\dbhome_1\NETWORK\ADMIN host后面地址全改为 " HOSTlocalhost " 。 以上两个配置文件修改完成后&#xff0c;Win R 在弹出框中输入 " SERVICES.MSC " &#xff0c;找到Oracle的服务&#xff08;OracleService&#xff09;…

ora12541+tns-01153未能处理字符串

操作系统&#xff1a; windows2008 数据库&#xff1a;oracle11g 数据库运行中突然连接不上 ora12541TNS:无监听程序 数据库服务器端查看&#xff1a; 使用dos端sqlplus登录正常 重启Oracle服务依然无法登陆 ora12541TNS plsql无法连接 使用 lsnrctl status 查看监听状态…

plsql远程访问数据库 解决 ora12170TNS 连接超时,ora-12541:TNS:无监听程序

自己在虚机linux安装了o12版本后&#xff0c;计划通过wins主机通过plsql操作oracle&#xff0c; 结果没有顺利链接&#xff0c;plsql报错 排错步骤: 1.查看网络是否通畅 打开cmd, ping 数据库IP 2. 查看端口是否通畅 打开cmd,tnsping 数据库IP 如果piing不通,可能是防火墙问…

ora-12541

描述&#xff1a;oracle 19c plsql登录报错 原因&#xff1a;修改了服务器的名称为ods 解决&#xff1a;修改listener.ora&#xff0c;tnsnames.ora文件中服务器名为ods&#xff0c;重启监听即可

oracle数据库只能用127.0.0.1和localhost登录,用ip无法登陆,提示ora12541监听错误解决办法

这些修改都在oracle安装完成后的服务端文件中修改&#xff0c;客户端里面的监听文件默认是没有的&#xff0c;也不需要配置 oracle服务端&#xff0c;客户端安装完成后&#xff0c; 服务端监听文件 E:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.or…

Oracle ORA12514 监听程序当前无法识别连接描述符中请求的服务

最简单的有可能是你的服务还没有开启&#xff0c;需要启动服务&#xff01;&#xff01;&#xff01;&#xff01; 在连接数据库的时候&#xff0c;有时会遇到一个“ORA12514&#xff1a;监听程序当前无法识别连接描述符中请求的服务”的错误&#xff0c;这个错误其实就是数据…

使用Navicat连接Oracle数据库及ORA-12541: TNS: 无监听程序、ORA-28547:connection to server failed、ORA-12514:TNS报错解决方案

1、Navicat的安装请参考:图形化界面之Navicat Premium 12 的安装与使用_蓝多多的小仓库的博客-CSDN博客_navicat premium12使用 2、打开Navicat,选择连接--->Oracle 3、配置常规和高级选项 这里服务名请参考: 为了避免后续存在权限问题,这里角色选择SYSDBA: 4、各项…