CUDA编程笔记(4)

news2024/10/7 2:21:47

文章目录

  • 前言
  • 1.CUDA的计时程序
  • 2.CUDA程序的计时
  • 影响GPU加速的关键
  • 总结


前言

怎么才能看出使用cuda编程,提高了程序的性能,一般都是通过比较程序运行的时间来验证。所以熟悉程序的运行时间的计时,可以查看优化的性能效果。

1.CUDA的计时程序

cuda提供了一种基于cuda事件的计时方式,在cuda编程书中介绍了如下的计时程序:

 // 定义变量
 cudaEvent_t start, stop;   
 // cudaEventCreate初始化变量
 CHECK(cudaEventCreate(&start));
 CHECK(cudaEventCreate(&stop));
 // 在计时的代码块之前要记录一个代表开始的事件
 CHECK(cudaEventRecord(start));
 // 需要添加cudaEventQuery操作刷新队列,才能促使前面的操作在GPU上执行
 cudaEventQuery(start); // 不用CHECK,返回值不对但不代表程序出错
 // 需要计时的代码块
 add<<<grid_size, block_size>>>(d_x, d_y, d_z, N); 
 // 在计时的代码块结束要记录一个代表结束的事件
 CHECK(cudaEventRecord(stop));
 // 要让主机等待事件stop被记录完毕
 CHECK(cudaEventSynchronize(stop));
 // 计算程序执行的时间差
 float elapsed_time;
 CHECK(cudaEventElapsedTime(&elapsed_time, start, stop));
 printf("Time = %g ms.\n", elapsed_time);
 // 销毁start和stop事件
 CHECK(cudaEventDestroy(start));
 CHECK(cudaEventDestroy(stop));

2.CUDA程序的计时

重复计时10次,计算平均值和误差。忽略第一次.第一次机器在CPU或者GPU上可能处于预热状态,测得的时间往往偏大.
在前面数组相加的程序里修改:

    float t_sum = 0;
    float t2_sum = 0;
    for (int repeat = 0; repeat <= NUM_REPEATS; ++repeat)
    {
        cudaEvent_t start, stop;
        CHECK(cudaEventCreate(&start));
        CHECK(cudaEventCreate(&stop));
        CHECK(cudaEventRecord(start));
        cudaEventQuery(start);

        add<<<grid_size, block_size>>>(d_x, d_y, d_z, N);

        CHECK(cudaEventRecord(stop));
        CHECK(cudaEventSynchronize(stop));
        float elapsed_time;
        CHECK(cudaEventElapsedTime(&elapsed_time, start, stop));
        printf("Time = %g ms.\n", elapsed_time);
			 // 忽略第一次.第一次机器可能处于预热状态,测得的时间往往偏大.
        if (repeat > 0)
        {
            t_sum += elapsed_time;
            t2_sum += elapsed_time * elapsed_time;
        }

        CHECK(cudaEventDestroy(start));
        CHECK(cudaEventDestroy(stop));
    }

这里在使用nvcc编译的时候,要在命令行添加-O3指令,是一个优化等级,表示三等级的优化,能够提升c++程序运行的性能。使用优化指令和不用相差比较大,大概2-3倍的样子。

影响GPU加速的关键

在上面的使用计时程序对cuda的核函数计时中,在使用单精度和双精度来对比运行时间,发现在GeForce RTX2080Ti上,双精度是单精度运行时间的差不多两倍关系。
定义使用双精度和单精度浮点数计算的程序:

//  在源程序中使用条件编译,定义双精度和单精度
#ifdef USE_DP
    typedef double real; // 给double和float类型取别名,方便直接使用real,后面统一做类型的修改
    const real EPSILON = 1.0e-15;
#else
    typedef float real;
    const real EPSILON = 1.0e-6f;
#endif

在编译时,使用命令行输入-D USE_UP可以指定选择使用双精度浮点数进行计算

使用单精度:
在这里插入图片描述
使用双精度:
在这里插入图片描述
上面的仅仅是计算的核函数里程序的运行时间,没有计算相对于c++程序里的内存分配和数据传递的时间。使用单精度,如果将数据传输的时候开始计时,发现cuda程序耗时显著增加。
在这里插入图片描述
运行时间:
在这里插入图片描述
而单单使用cpu的程序,运行时间:
在这里插入图片描述
可以发现:

  • cuda程序里,数组相加,使用核函数所占的时间比很小,基本都是数据传输消耗了较多的时间。相对于直接使用cpu来说,可能性能得不到提升。
    在cuda工具箱中,可以使用nvprof指令,去查看程序各部分执行时间的消耗情况:
    在这里插入图片描述很直观的可以分析出数据传输占据了主要的执行时间,核函数最大消耗的时间才用了2.1864ms占总的时间的0.81%。

综上可以发现,数据在主机和设备之间的传输消耗的时间比较大。那为什么说使用cuda性能能得到提升呢?

  • 通过核函数的时间对比,可知在GPU上存在很多核心,计算速度要比CPU上快的多。而应该是数组相加这个操作太简单了,所以在直观上体现不了cuda的加速情况。后面通过使用较为复杂的浮点数运算,证明cuda能够很大程度的提升程序的性能。还有就是既然数据传输占总的时间很大,只要在复杂的操作中,开始进行一次的传输,后面尽量避免大数据的传输,就可以获得可观的性能提升。

这里总结一下,影响GPU加速的关键就是两点:
(1)数据传输的比例:多在GPU上进行计算,避免过多的数据传输,数据经过PCIe传递。
(2)浮点数计算的算术强度:复杂的浮点运算选择在GPU上进行。

书中还提到了,不同型号的GPU在单精度和双精度上两者执行时间的比值,对于算术强度较高的问题,在使用双精度浮点运算时,Tesla系列的GPU相对于GeForce系列的GPU更具有优势。在单精度上都产不多,GeForce系列的GPU更具有性价比。

总结

cuda程序执行的计时方式和GPU性能加速的分析
参考:
如博客内容有侵权行为,可及时联系删除!
CUDA 编程:基础与实践
https://docs.nvidia.com/cuda/
https://docs.nvidia.com/cuda/cuda-runtime-api
https://github.com/brucefan1983/CUDA-Programming

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173155.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日亿题(面试题)

每日亿题(面试题) new Fn和new Fn()有什么区别&#xff1f; 1.首先如果是为传参数的情况下结果是相同的 2.如果是获取属性new Fn() 正常执行&#xff0c;而 new Fn 报错 3.不带括号不能给构造函数传参 分析比较 opacity: 0、visibility: hidden、display: none 优劣和适用…

Spring看这一篇文章就够了

第一章 Spring简介 第1节 Spring的介绍 Spring官网地址 1https://spring.ioSpring的介绍 1Spring是一个开放源代码的设计层面框架&#xff0c;他解决的是业务逻辑层和其他各层的松耦合问题&#xff0c;因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003年兴起的一…

4.2w字,详细的带你认识基础I/O【Linux--基础IO】

前言 相信大家最开始都挺疑惑的&#xff0c;什么I/O。在计算机操作系统中&#xff0c;所谓的I/O实则就是输入&#xff08;Input&#xff09;和输出&#xff08;Output&#xff09;&#xff0c;也可以理解为读&#xff08;Read&#xff09;和写&#xff08;Write&#xff09;&…

Linux常用命令——tar命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) tar Linux下的归档使用工具&#xff0c;用来打包和备份。 补充说明 tar命令可以为linux的文件和目录创建档案。利用tar&#xff0c;可以为某一特定文件创建档案&#xff08;备份文件&#xff09;&#xff0c;也…

mysql 基本组成

1 mysql 基本组成 1.1、mysql连接器的工作流程: 1.2、查看连接状态: show processlist; Note:客户端太长时间没动静 就自动断开 这个时间是由wait_timeout参数控制的,默认8h 长连接短链接 长连接是链接成功后,如果客户端持续有请求,则使用同一个链接[尽量使用长连接,因为每次…

组件间通信

1、Vue组件的嵌套关系 1.1、认识组件的嵌套 前面我们是将所有的逻辑放到一个App.vue中&#xff1a; 在之前的案例中&#xff0c;我们只是创建了一个组件App&#xff1b;如果我们一个应用程序将所有的逻辑都放在一个组件中&#xff0c;那么这个组件就会变成非常的臃肿和难以维…

【网络通信】【电信运营商实战工程师】思科设备篇-思科设备园区网实战

电信运营商实战工程师系列文章. 思科设备篇-思科设备园区网实战. 文章目录1. 思科设备链路捆绑实战2. 思科设备VRRP、HSRP实战3. 思科设备ACL实战全集4. 思科设备RIP协议实战5. 思科设备OSPF协议全集-理论6. 思科设备OSPF协议全集-实战1. 思科设备链路捆绑实战 知识点&#xff…

【中科微北斗+GPS模块经纬度数据解析详细教程-附免费代码工程】

中科微北斗GPS模块经纬度数据解析详细教程-附免费代码工程简介准备工作PC端需要用到的工具代码下载地址GD32F103C8T6最小系统板代码实现GD32串口引脚定义如下&#xff1a;串口的初始化串口0初始化代码&#xff1a;串口1初始化代码串口的输入串口0的输入代码如下&#xff1a;串口…

嵌入式Linux-线程的开始

1. 线程的开始 1.1 线程的含义 学习了进程相关的知识内容&#xff0c;对进程有了一个比较全面的认识和理解&#xff0c;从今开始呢&#xff0c;我们要学习一个新的概念&#xff0c;叫做线程&#xff01; 那什么是线程呢? 与进程类似&#xff0c;线程是允许应用程序并发执行…

java中的方法2023016

定义方法&#xff08;VS函数&#xff09;&#xff1a; 方法是类或对象的行为特征的抽象&#xff0c;方法是类或对象最重要的组成部分。但从功能上来看&#xff0c;方法完全类似于传统结构化程序设计里的函数。区别是&#xff1a;Java里的方法不能独立存在&#xff0c;所有的方法…

《精力管理》阅读笔记

目录 什么是精力及如何管理精力 高效表现有节奏——劳逸结合的平衡 管理精力的三个步骤 明确目标——知道什么最重要才能全情投入 正视现实——你的精力管理做得如何 付诸行动——积极仪式习惯的力量 精力管理的四个基本原则 体能精力——为身体添柴加火 情感精力——把…

微信小程序----全局数据共享

1.什么是全局数据共享 全局数据共享&#xff08;又叫做:状态管理&#xff09;是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX等。 2.小程序中的全局数据共享方案 在小程序中&#xff0c;可使用 mobx-miniprogram 配合 mobx-miniprog…

【SAP Abap】X档案:SAP Native SQL 简介及本地数据库访问实现方式(EXEC SQL、ADBC、AMDP)

SAP Native SQL 简介及本地数据库访问实现方式&#xff08;EXEC SQL、ADBC、AMDP&#xff09;1、SAP Open SQL 与 Native SQL 的特点2、实现方式方式一&#xff1a;Native SQL&#xff08;Exec SQL&#xff09;&#xff08;1&#xff09;获取单值&#xff08;2&#xff09;获取…

iOS上架appstore详细教材

假如你用原生xcode开发&#xff0c;上架是相对简单。 但假如是用hbuilderx这些uniapp框架开发&#xff0c;没有mac电脑&#xff0c;没有xcode&#xff0c;那么还能上架吗&#xff1f;是可以的&#xff0c;你看完这篇文章&#xff0c;就知道如何在没有mac电脑的情况下&#xff…

【小知识】目标检测各类指标概念总结

文章目录前言一、AP&#xff08;Average Precision&#xff09;1.1 TP&#xff08;True Positive&#xff09;、FP&#xff08;False Positive&#xff09;、FN&#xff08;False Negative&#xff09;1.2 Precision&#xff08;查准率&#xff09;、Recall&#xff08;召回率/…

【LeetCode】Day201-重新安排行程

题目 332.重新安排行程【困难】 题解 这道题的几个难点&#xff1a; 一个行程中&#xff0c;如果航班处理不好容易变成一个圈&#xff0c;成为死循环有多种解法&#xff0c;字母序靠前排在前面&#xff0c;应该如何记录映射关系&#xff1f;使用回溯法&#xff0c;终止条件…

贪心 376. 摆动序列

376. 摆动序列 难度中等827 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9,…

opencv的图像基本操作_3

模板匹配 模板匹配和卷积很像&#xff0c;模板在原图像上滑动&#xff0c;并在滑过的区域上计算匹配数值&#xff0c;通过匹配数值衡量模板匹配程度&#xff0c;opencv中有6种计算方法&#xff0c;从原点开始计算&#xff0c;将每次计算的结果放到一个矩阵&#xff0c;最后输出…

CSS 加载进度条

CSS 加载进度条 环形加载条 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>环形加载条</title><style type"text/css">.box {width: 200px;height: 200px;border: 1px solid silver;display: flex…

永磁同步电机全速域控制指南

一直都想知道永磁同步电机的转速从零增加到极限这个过程会发生什么&#xff0c;这篇文章介绍一下永磁同步电机全速域矢量控制的全过程&#xff0c;即电机的转速从零开始逐渐增加&#xff0c;如何设计电流环电流使得电机输出恒定转矩&#xff0c;且保持转速稳定。能把这个过程想…