• 问题记录:GPU显卡提高后,代码总体运行效率没有提高


    问题:GPU显卡提高后,代码总体运行效率没有提高

    原先显卡NIVIDA T400换成NVIDIA RTX A4000,CUDA核心(物理GPU线程单位)从三百多提升到了六千多,但是程序总体运行的时间没有变化。

    原因分析

    1. 显卡没用上或者没有配置好,实际上还是用CPU在跑。
    2. GPU跑了,但是GPU和CPU并行效率没有对齐。

    检查是否有用上GPU

    任务管理器

    在任务管理器中看程序运行后CUDA调用GPU的情况。
    在这里插入图片描述

    nvidia-smi

    打开cmd命令行输入nvidia-smi即可查看NVIDIA GPU使用状况。
    在这里插入图片描述

    NIVIDA性能分析工具nvprof、nvvp和Nsight Systems

    前面任务管理器都只能看某些时刻电脑整体GPU占用情况,但接下来介绍的三个性能分析工具能够显示程序很详细的GPU、CPU使用情况,甚至能精确到某个函数。

    在Windows机器环境下,在安装好CUDA Toolkit后则自带了nvprof / nvvp等工具。nvprof / nvvp等工具能够计算GPU和CPU使用情况,以此来实现对程序的性能分析。

    两者区别:nvprof是命令行测试CUDA程序,nvvp则是带有界面的测试CUDA程序。

    对于CUDA版本比较低的,可以使用nvprof / nvvp工具做性能测试,但是版本高了之后,就会报错。

    在这里插入图片描述
    原因在于官方把更高版本的cuda从nvprof和nvvp迁移到了Nsight Systems。

    上述工具可能会遇到的问题:

    • nvprof报错:找不到cupti64_2021.2.0.dll,无法继续执行代码…
      方法:路径NVIDIA GPU Computing Toolkit\CUDA\v11.4\extras\CUPTI\lib64下面找到cupti64_2021.2.0.dll,复制到NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin中。
    • nvvp报错:An error has occurred.See the log file…
      在这里插入图片描述
      方法:原因是电脑没有安装JDK8,去网上搜索一下JDK8然后安装就行。
    • nvvp使用:打开后,进行create new session,File选择你要进行测性能的可执行文件(exe),一般VS程序Debug文件夹下会有程序对应可执行的exe。

    代码断点

    在CUDA选中显卡信息和分配GPU内存部分打断点或者输出一下信息,看看显卡信息是否正确以及内存是否有正确分配。

    // 查看选中GPU的信息
    cudaDeviceProp prop;
    cudaSetDevice(device_id);// 选中编号为device_id的GPU设备
    cudaGetDeviceProperties(&prop, device_id);// 获取device_id的GPU设备信息,可以在这里打个断点看看选中的GPU信息是否正确
    
    // 分配GPU内存
    status = cudaMalloc((void**) &data, sizeof(int)*n);// 为data分配长度为n的int类型GPU内存,查看status是否为success判断是否使用了GPU
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    检查GPU和CPU并行效率是否对齐

    通过在代码设置时间戳,来记录CPU和GPU运行的时间,来判断是否达成并行的条件。

    举例子:一个程序需要完成获取、处理、输出数据的工作,处理数据的部分可以交给GPU完成,其余交给CPU,GPU和CPU之间能够并行工作。如果CPU获取数据的时间>GPU处理数据的时间,那么GPU处理的速度再快,整体的运行时间也不会有多少改变,因为GPU每次处理完数据都要先等CPU获取完数据。但是,如果CPU获取数据的时间

    GPU显卡提高后,代码总体运行效率没有提高,可能原因就是“CPU获取数据的时间>GPU处理数据的时间”。

    C++通过时间戳GetTickCount()获取运行时间,来计算GPU和CPU部分代码的时间,来判断是否有上述情况:

    #include 
    #include
    int main(){
    	DWORD start_time=GetTickCount();
    	{//此处为被测试代码}
    	DWORD end_time=GetTickCount();
    	cout<<"The run time is:"<<(end_time-start_time)<<"ms!"<<endl;//输出运行时间
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    机器学习入门(五)回归问题中的曲线过拟合问题及解决
    每个后端都应该了解的OpenResty入门以及网关安全实战
    SecXOps 核心技术能力划分
    Python urllib
    Cannot find proj.db
    SpringCloud(一)--Eurea
    C++ 左值、右值、左值引用以及右值引用
    〖Python 数据库开发实战 - MySQL篇㉝〗- 数据的导入与导出
    【Go】rsrc不是内部或外部命令、无法将“rsrc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称 解决方法
    WuThreat身份安全云-TVD每日漏洞情报-2023-09-20
  • 原文地址:https://blog.csdn.net/qq_40306845/article/details/133969807