提升CUDA程序运行效率的几个关键点

2023-05-16

目录

1、明确计算机中GPU卡片的计算资源,决定变量的性质(constant,share还是global)以及Grid,Block的维度,充分并合理利用GPU显卡的资源

2、提高PCI接口与GPU显卡的数据吞吐量

3、优化GPU内部存储到处理器之间的数据传输效率

4、利用性能分析工具进行程序性能分析,根据建议进行程序的性能优化


最近由于项目需要,需要用MPI+CUDA混合编程提高程序运行效率。相对于MPI并行程序编程,要想充分利用CUDA的资源利用率,还是要考虑很多方面的内容,根据查找的一些相关资料,将提升GPU显卡吞吐率以及利用效率的方法归纳如下,如有问题,敬请批评指正。下面是进行CUDA编程的大致流程,为了避免混乱,会将相关的详细内容放到链接所示的位置。

1、明确计算机中GPU卡片的计算资源,决定变量的性质(constant,share还是global)以及Grid,Block的维度,充分并合理利用GPU显卡的资源

在进行程序编写前需要明确知道计算机资源,尤其是显卡资源是很宝贵的,在实际编程中需要进行综合考虑,然后再进行参数的具体设置。首先得明白显卡的基本的一些信息,可以通过安装NVIDIA_SAMPLES来进行显卡基本信息的获取,NVIDIA_CUDA-9.1_Samples/1_Utilities/deviceQuery,我的机器的GPU显卡的具体信息如下:

这里面的每一条信息都是很重要的,其中我们平时用的最多的还是“Total amount of global memory,Multiprocessors,  CUDA Cores/MP,L2 Cache Size,Maximum Texture Dimension Size (x,y,z),Total amount of constant memory,Total amount of shared memory per block,Total number of registers available per block,Warp size,Maximum number of threads per multiprocessor,Maximum number of threads per block,Max dimension size of a thread block (x,y,z),Max dimension size of a grid size    (x,y,z),Integrated GPU sharing Host Memory,Support host page-locked memory mapping,Device has ECC support”等等,在地球物理相关的CUDA程序编写中,关注这些参数就已经足够了。对于一个程序在运行时对显卡资源的分配问题,详细内容可以点击下面两个链接。

具体可参考:GPU硬件结构和程序具体参数设置_yu132563的专栏-CSDN博客

CUDA程序编写具体参数设置_yu132563的专栏-CSDN博客

2、提高PCI接口与GPU显卡的数据吞吐量

  • 使用流并行及统一内存、zerocopy等方法掩盖PCI接口与GPU显卡之间进行数据传输的时间延迟
  • 核函数执行和数据传输的重叠

3、优化GPU内部存储到处理器之间的数据传输效率

主要方法如下:

  • 使用共享内存减少全局内存读取次数
  • 减少全局内存的重复数据的重复访问,此处大有学问,需要设计我们的线程组织模式,最大可能利用共享内存,可参考矩阵乘法优化问题;
  • 把全局内存绑定为纹理
  • 纹理的存取速度要远高于全局内存

  • 减少bank conflict, 让不同线程读取连续内存
  • Tesla 的每个 SM 拥有 16KB 共享存储器,用于同一个线程块内的线程间通信。为了使一个 half-warp 内的线程能够在一个内核周期中并行访问,共享存储器被组织成 16 个 bank,每个 bank 拥有 32bit 的宽度,故每个 bank 可保存 256 个整形或单精度浮点数,或者说目前的 bank 组织成了 256 行 16 列的矩阵。如果一个 half-warp 中有一部分线程访问属于同一bank 的数据,则会产生 bank conflict,降低访存效率,在冲突最严重的情况下,速度会比全局显存还慢,但是如果 half-warp 的线程访问同一地址的时候,会产生一次广播,其速度反而没有下降。在不发生 bank conflict 时,访问共享存储器的速度与寄存器相同。在不同的块之间,共享存储器是毫不相关的。
  • 尺寸和对齐的要求内存对齐
  • 因为GPU 上的内存控制器,从某个固定的倍数地址开始读取,才会有最高的效率(例如 16 bytes 的倍数)。分配内存时使用cudaMallocPitch替代cudaMalloc,相应 cudaMemcpy2D替代 cudaMemcpy。(这其实和(2)中原理类似)

  • 合并访问
  • 详情可参考:CUDA总结:合并访问coalesced_Kelvin_Yan的专栏-CSDN博客_cuda合并访问
  • 使用流并行
  • 流并行属于,任务级别的并行,当我们有几个互不相关的任务时,可以写多个核函数,资源允许的情况下,我们将这些核函数装载到不同流上,然后执行,这样可以实现更粗粒度的并行。
    实验中发现,流并行的效率和增加一个线程网格的维度的方法的效率一样。也可以使用没线程默认流来进行流并行

4、利用性能分析工具进行程序性能分析,根据建议进行程序的性能优化

nvvp和nvprof工具进行性能分析,进一步提高计算性能

参考文献:

CUDA中Bank conflict冲突_smsmn的专栏-CSDN博客

CUDA总结:合并访问coalesced_Kelvin_Yan的专栏-CSDN博客_cuda合并访问

CUDA程序优化方法_changyi9995的博客-CSDN博客_cuda优化

CUDA2.2-原理之存储器访问 - 仙守 - 博客园

CUDA编程——zero copy_道道道人间道的博客-CSDN博客_cuda zerocopy

cuda Global Memory Access - 灰太狼锅锅 - 博客园

CUDA学习--CUDA流_Yi_M的博客-CSDN博客_cuda 流

CUDA编程第六章: 流和并发_Janus-CSDN博客

CUDA 7 Stream流简化并发性 - 吴建明wujianming - 博客园

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提升CUDA程序运行效率的几个关键点 的相关文章

随机推荐

  • C++头文件包含顺序问题

    C 43 43 中类的声明和类的定义分开几乎成了一个不成文的规定 这样做的好处是使得类的声明和实现分开 xff0c 清晰明了 xff0c 同时便于库函数发布 但是在实际编程中由此也常常引起了一些由于头文件的包含顺序问题而产生的符号未定义的编
  • 详解printf重定向到文件中,打印日志的实现

    printf是将信息打印到终端 xff0c 但是有时当我们需要打印的信息比较多时 xff0c 终端无法将所有信息都能够保留在屏幕上 xff0c 这样我们就不能在终端获取我们想要的信息了 xff0c 重定向很好的帮我们解决了这个问题 xff0
  • 计划

    文档计划 读书的时候 2010年左右 由于和导师做了一些涉及单片机的项目 xff0c 狠狠熟悉了一把C语言 xff0c 所以试图写一个实时内核 xff0c 但是由于涉及大量的硬件知识 xff0c 底层汇编和任务栈之类的东西 xff0c 而这
  • CMOS内核--序言

    CMOS内核 序言 本文介绍一些CMOS中需要用的基础知识 由于在单片机系统中不会有MMU所以单片机系统中的每个任务就是一个线程 xff0c 共用系统的地址空间 xff0c 为了精确性 xff0c 后文中措辞中使用线程替换任务 xff0c
  • 欧拉角和旋转矩阵之间的转换

    一 什么是欧拉角 在3D 空间中 xff0c 表示物体的旋转可以由三个欧拉角来表示 xff1a pitch围绕X轴旋转 xff0c 叫俯仰角 yaw围绕Y轴旋转 xff0c 叫偏航角 roll围绕Z轴旋转 xff0c 叫翻滚角 这三个角的顺
  • C++编译之(1)-g++单/多文件/库的编译及C标准的发展历程

    g 43 43 编译入门 本文为您介绍g 43 43 的编译用法 xff1b 通过从最简单的单文件编译 xff0c 到多文件编译 xff0c 再到动态库 静态库的编译及使用 xff1b 例子都经过实际编译并运行 xff0c 可谓全网最良心之
  • STM32F103-寄存器开发-2

    上一篇博客中我已经配置好了对应的时钟 xff0c 接下来就是对GPIOC口进行操作了 为此我们需要配置端口配置寄存器 xff0c 但是在用户手册中查阅 xff0c 可以发现有两个寄存器 xff0c CRL和CRH xff0c 我们应该使用哪
  • 25.UART串口发送过程与配置

    UART串口收发过程与配置 参考资料 STM32Fx中文参考手册 第26章 xff1a 通用同步异步收发器章节 开发板配套教程 STM32Fx开发指南 串口实验章节 笔记基于正点原子官方视频 视频连接https www bilibili c
  • c语言HTTP服务器,超级简易版。

    算是对linux多线程的复习把 xff0c 尝试这用socket写了一个简单的HTTP服务器 xff0c 当访问它的时候它会给你发送一个HTML文件 xff0c 这个HTML文件需要自己写 代码 span class hljs prepro
  • linux POST请求

    linux POST请求 curl https baidu com X POST H key1 value1 H key2 value2 d name test age 23 i 说明 xff1a H header 后接key value对
  • CPPREST处理跨域问题

    本例使用的代码框架非常简单 按照下面这个路径搭建即可 https blog csdn net youyicc article details 108261287 问题由来 网页端需要动态检测C 服务器这边服务是否正常运行 所以采用的方式是h
  • 内存存取区——堆和栈

    一 预备知识 程序的内存分配 一个由c C 43 43 编译的程序占用的内存分为以下几个部分 1 栈区 xff08 stack xff09 由编译器自动分配释放 xff0c 存放函数的参数值 xff0c 局部变量的值等 其操作方式类似于数据
  • ROS中RVIZ坐标系及TF坐标系转换

    RVIZ坐标系 X轴 红色 Y轴 绿色 Z轴 蓝色 YAW 偏航角 绕Z轴旋转 PITCH 俯仰角 绕Y轴旋转 ROLL 滚转角 绕X轴旋转 符合右手坐标系原则 利用TF进行坐标系转换 采用以下指令进行转换 xff0c 其中frame id
  • 【C语言】长度为0的数组

    最近在看代码的时候发现一个好玩的事情 xff0c 长度为0的数组 xff0c 在此记录一下 在网上看到的这个说是只有GNU C才支持的特性 xff0c 因此考虑跨平台或者可移植特点需要慎用 话不多说 xff0c 上案例才有感觉 span c
  • jetson xavier nx使用usb线刷机后开机黑屏闪屏

    情况一 比较常见 xff09 由于刷机是的flash接口是调在右边的 xff0c 如下图所示 解决方法 xff1a 故在刷机成功后 xff0c 连接显示屏后要将flash接口调到 左侧 情况二 在对jetson xavier nxs进行刷机
  • python牛客网输入输出处理

    python 笔试输入 sys stdin readline和input 非常有用 xff01 xff01 xff09 https www jianshu com p 6f14ca3290ee input vs sys stdin read
  • Demo-简单使用libcurl静态库访问网址

    在开始前请先准备好下面的文件 xff1a 1 调试版的libcurl静态库libcurld lib xff0c 可以在网上下载或自己编译 xff1b 2 头文件 xff0c curl h curlver h easy h mprintf h
  • QQ 浏览器(iOS版)崩溃信息研究

    今天碰巧下载了QQ浏览器iOS版本 xff0c 居然一启动就挂了 后来从手机里面把崩溃信息导出来 xff0c 仔细研究下 xff0c 把研究的结果放到网上 xff0c 与大家分享下 先把我导出的崩溃信息放出来 Incident Identi
  • EXCEL利用VBA自由控制图表绘图区大小

    用好VBA的话确实可以给你再办公室的工作效率带来质的提升 如果有人跟你说你可以用Python什么的语言处理Excel balabala的 xff0c 你可以无视他了 当然python可以处理很多事情 xff0c 但是EXCEL自带的作图工具
  • 提升CUDA程序运行效率的几个关键点

    目录 1 明确计算机中GPU卡片的计算资源 xff0c 决定变量的性质 xff08 constant xff0c share还是global xff09 以及Grid xff0c Block的维度 xff0c 充分并合理利用GPU显卡的资源