[9] CUDA性能测量与错误处理

CUDA性能测量与错误处理

  • 讨论如何通过CUDA事件来测量它的性能
  • 如何通过CUDA代码进行调试

1.测量CUDA程序的性能

1.1 CUDA事件

  • CPU端的计时器可能无法给出正确的内核执行时间
  • CUDA事件等于是在你的CUDA应用运行的特定时刻被记录的时间戳,通过使用CUDA事件API,由GPU来记录这个时间戳
  • 使用CUDA测量时间需要两个步骤:创建事件和记录事件,记录事件(开始时间与结束时间)
  • 代码如下:
#include "stdio.h"
#include<iostream>
#include <cuda.h>
#include <cuda_runtime.h>
//Defining number of elements in Array
#define N	50000
//Defining Kernel function for vector addition
__global__ void gpuAdd(int* d_a, int* d_b, int* d_c) {//Getting Thread index of current kernelint tid = threadIdx.x + blockIdx.x * blockDim.x;while (tid < N){d_c[tid] = d_a[tid] + d_b[tid];tid += blockDim.x * gridDim.x;}}int main(void) {//Defining host arraysint h_a[N], h_b[N], h_c[N];//Defining device pointersint* d_a, * d_b, * d_c;//----------创建事件记录起止时间---------------------cudaEvent_t e_start, e_stop;cudaEventCreate(&e_start);cudaEventCreate(&e_stop);//第一次记录时间戳cudaEventRecord(e_start, 0);// allocate the memorycudaMalloc((void**)&d_a, N * sizeof(int));cudaMalloc((void**)&d_b, N * sizeof(int));cudaMalloc((void**)&d_c, N * sizeof(int));//Initializing Arraysfor (int i = 0; i < N; i++) {h_a[i] = 2 * i * i;h_b[i] = i;}// Copy input arrays from host to device memorycudaMemcpy(d_a, h_a, N * sizeof(int), cudaMemcpyHostToDevice);cudaMemcpy(d_b, h_b, N * sizeof(int), cudaMemcpyHostToDevice);//Calling kernels passing device pointers as parametersgpuAdd << <512, 512 >> > (d_a, d_b, d_c);//Copy result back to host memory from device memorycudaMemcpy(h_c, d_c, N * sizeof(int), cudaMemcpyDeviceToHost);cudaDeviceSynchronize();//再次记录时间戳cudaEventRecord(e_stop, 0);//等待所有GPU工作都完成cudaEventSynchronize(e_stop);float elapsedTime;//计算时间插值cudaEventElapsedTime(&elapsedTime, e_start, e_stop);printf("Time to add %d numbers: %3.1f ms\n", N, elapsedTime);int Correct = 1;printf("Vector addition on GPU \n");//Printing result on consolefor (int i = 0; i < N; i++) {if ((h_a[i] + h_b[i] != h_c[i])){Correct = 0;}}if (Correct == 1){printf("GPU has computed Sum Correctly\n");}else{printf("There is an Error in GPU Computation\n");}//Free up memorycudaFree(d_a);cudaFree(d_b);cudaFree(d_c);return 0;
}

1.2 NVIDIA Visual Profiler

  • 如果你在程序中使用了CUDA,代码的性能并未提升,在这种情况下,能够可视化地查看代码的哪些部分花费了最长的时间完成将非常有用,这叫剖析内核执行代码
  • 英伟达提供了以上用途的工具 nvvp ,就在标准的CUDA安装包里,在电脑的如下路径可以被找到:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\libnvvp
    在这里插入图片描述
  • 执行它需要安装java环境,即安装jdk8即可,可以去官网下载,也可以从我的链接 jdk8下载,然后需要配置环境变量C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\extras\CUPTI\lib64 C:\Program Files\Java\jdk-1.8\bin
    在这里插入图片描述
  • 打开nvvp 会出现如下窗口,此工具会分析你的代码执行过程,采集GPU上的性能数据,运行结束后会给你一个详细的报告,包括每个内核的执行时间,代码中每个详细操作的时间戳,以及代码存储器的使用情况
    在这里插入图片描述
  • 想要得到详细报告,可依次点击 File -> New Session,然后在弹出的对话框中选择程序的.exe文件
    在这里插入图片描述
  • Profiler 是分析内核执行情况的重要工具,它也可以用来比较两个内核的性能。它会告诉你就是是代码里的何种操作拉低了性能

2. CUDA中的错误处理

  • 如果系统中没有可用的GPU设备怎么办?显存不足怎么办?
  • 学会在CUDA程序里边添加错误处理代码很有好处
#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <stdio.h>__global__ void gpuAdd(int *d_a, int *d_b, int *d_c) {*d_c = *d_a + *d_b;
}
int main()
{//Defining host variablesint h_a, h_b, h_c;//Defining Device Pointersint *d_a, *d_b, *d_c;//Initializing host variablesh_a = 1;h_b = 4;//定义错误结果变量cudaError_t cudaStatus;// Allocate GPU buffers for three vectors (two input, one output)    .cudaStatus = cudaMalloc((void**)&d_c, sizeof(int));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!");goto Error;}cudaStatus = cudaMalloc((void**)&d_a, sizeof(int));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!");goto Error;}cudaStatus = cudaMalloc((void**)&d_b, sizeof(int));if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMalloc failed!");goto Error;}// Copy input vectors from host memory to GPU buffers.cudaStatus = cudaMemcpy(d_a,&h_a, sizeof(int), cudaMemcpyHostToDevice);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}cudaStatus = cudaMemcpy(d_b, &h_b, sizeof(int), cudaMemcpyHostToDevice);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}// Launch a kernel on the GPU with one thread for each element.gpuAdd<<<1, 1>>>(d_a, d_b, d_c);// Check for any errors launching the kernelcudaStatus = cudaGetLastError();if (cudaStatus != cudaSuccess) {fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));goto Error;}// Copy output vector from GPU buffer to host memory.cudaStatus = cudaMemcpy(&h_c, d_c, sizeof(int), cudaMemcpyDeviceToHost);if (cudaStatus != cudaSuccess) {fprintf(stderr, "cudaMemcpy failed!");goto Error;}printf("Passing Parameter by Reference Output: %d + %d = %d\n", h_a, h_b, h_c);
Error:cudaFree(d_c);cudaFree(d_a);cudaFree(d_b);return 0;
}
  • -----------------------END----------------------------

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

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

相关文章

UVa1466/LA4849 String Phone

UVa1466/LA4849 String Phone 题目链接题意分析AC 代码 题目链接 本题是2010年icpc亚洲区域赛大田赛区的G题 题意 平面网格上有n&#xff08;n≤3000&#xff09;个单元格&#xff0c;各代表一个重要的建筑物。为了保证建筑物的安全&#xff0c;警察署给每个建筑物派了一名警察…

MFC 用Imm类库实现输入法修改输入模式

1.导入Imm类库&#xff0c;电脑里都有 #include <Imm.h> #pragma comment(lib, "imm32.lib")2.在想要的地方增加代码 HIMC himc ImmGetContext(m_hWnd);if (himc ! NULL) {ImmSetOpenStatus(himc, TRUE);ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL,…

时代终结,微软宣布淘汰VBScript;Flink漏洞被广泛利用;Grandoreiro银行木马强势回归,1500多家银行成攻击目标 | 安全周报0524

揭秘SolarMarker恶意软件&#xff1a;多层次基础设施让清除工作陷入困境 Recorded Future的新发现表明&#xff0c;SolarMarker信息窃取恶意软件背后的持续威胁行为者已经建立了一个多层次的基础设施&#xff0c;以使执法部门的清除工作变得复杂。 该公司在上周发布的一份报告…

SwiftUI中AppStorage的介绍使用

在Swift中&#xff0c;AppStorage是SwiftUI中引入的一个属性包装器&#xff0c;在这之前我们要存储一些轻量级的数据采用UserDefaults进行存取。而AppStorage用于从UserDefaults中读取值&#xff0c;当值改变时&#xff0c;它会自动重新调用视图的body属性。也就是说&#xff0…

React@16.x(11)ref

目录 1&#xff0c;介绍1.1&#xff0c;得到的结果 2&#xff0c;参数类型2.1&#xff0c;字符串&#xff08;不再推荐&#xff09;2.2&#xff0c;对象2.3&#xff0c;函数函数调用时机 3&#xff0c;注意点 1&#xff0c;介绍 reference 引用。和 vue 中的 refs 类似&#x…

IEC60870-5-104通信规约 | 报文解析 | 组织报文与解析报文(C++)

文章目录 一、IEC60870-5-104通信规约1.IEC104的报文结构2.IEC104的报文格式--I/U/S格式2.1 I帧2.2 U帧2.3 S帧 3.应用服务数据单元ASDU 二、IEC60870-5-104规约通信过程报文帧解析三、组织报文与解析报文&#xff08;C&#xff09; 一、IEC60870-5-104通信规约 IEC60870-5-104…

golang 守护进程管理

添加守护进程 vim /etc/systemd/system/xxx.service [Unit] DescriptionGo Socket Service Afternetwork.target[Service] Typesimple ExecStart/data/quwan/quwan_ws WorkingDirectory/data/quwan # 停止前发送信号 ExecStop/bin/kill -SIGTERM $MAINPID # 如果超过20s 进程…

笔记-Python lambda

在学习python的过程中&#xff0c;lambda的语法时常会使人感到困惑&#xff0c;lambda是什么&#xff0c;为什么要使用lambda&#xff0c;是不是必须使用lambda&#xff1f; 下面就上面的问题进行一下解答。 1、lambda是什么&#xff1f; 看个例子&#xff1a; 1 g lambda…

什么是GPT-4o,推荐GPT-4o的获取使用方法,使用GPT4o模型的最新方法教程(2024年5月16更新)

2024年5月最新GPT-4o模型使用教程和简介 2024年5月最新GPT-4o模型使用教程和简介 2024 年 5 月 13 日&#xff0c;openai 发布了最新的模型 GPT4o。 很多同学还不知道如何访问GPT-4、GPT-4 Turbo和GPT-4o等模型&#xff0c;这篇文章介绍如何在ChatGPT中访问GPT-4o&#xff0…

milvus索引

Milvus是一个开源的向量数据库引擎&#xff0c;旨在支持大规模向量相似度搜索和分析。索引在Milvus中扮演着非常重要的角色&#xff0c;它们用于加速向量数据的检索。下面详细介绍一下Milvus中的索引&#xff1a; 1. 索引类型 Milvus支持多种索引类型&#xff0c;每种类型都适…

无人机侦察:雷达系统概述

一、雷达基本原理 无人机侦察中的雷达系统主要基于无线电波的传播和反射原理。雷达发射机产生特定频率的电磁波&#xff0c;并通过天线以定向波束形式向空间发射。当这些电磁波遇到目标时&#xff0c;部分能量会被反射回来&#xff0c;被雷达接收机捕获。通过测量发射和接收电…

基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】

前言 该系统采用SpringBootVue前后端分离开发&#xff0c;前端是一个单独的项目&#xff0c;后端是一个单独的项目。   技术栈&#xff1a;SpringBootVueMybatisRedisMysql   开发工具&#xff1a;IDEA、Vscode   浏览器&#xff1a;Chrome   开发环境&#xff1a;JDK1…

Pytorch 笔记

执行下面这段代码后&#xff0c;为什么返回的是 2 &#xff1f; vector torch.tensor([7, 7]) vector.shape为什么返回的是 torch.Size([2])&#xff1f; 当你创建一个PyTorch张量时&#xff0c;它会记住张量中元素的数量和每个维度的大小。在你的代码中&#xff0c;torch.t…

通过 js 调起微信官方的微信支付api

通过 js 调起微信官方的微信支付api function onBridgeReady() {WeixinJSBridge.invoke(getBrandWCPayRequest, { "appId": "wx2421b1c4370ec43b", // 公众号ID&#xff0c;由商户传入 "timeStamp": "1395712654", // 时间戳&quo…

动态插入HTML内容有哪些常见用法

动态插入HTML内容的常见用法包括但不限于以下几种情况&#xff1a; 用户交互反馈&#xff1a;当用户在网页上进行某些操作时&#xff08;如点击按钮、提交表单等&#xff09;&#xff0c;可以使用JavaScript动态插入HTML内容来提供即时的反馈或结果。例如&#xff0c;当用户点…

vue3第三十五节(TS 之 泛型)

本节介绍 ts 中泛型的常用情景 1 什么是泛型 泛型的本质是参数化类型&#xff0c;也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中&#xff0c;分别称为泛型类、泛型接口、泛型方法。 泛型使用<T>来定义类型&#xff0c;<T…

使用canarytokens进行入侵检测

canarytokens 基本概念 canarytokens是一种用于识别网络入侵的工具。它们是一种虚拟的“蜜罐”&#xff0c;可以在网络上放置&#xff0c;当有人尝试访问它们时&#xff0c;可以立即触发警报&#xff0c;以便及时发现潜在的安全威胁。这些token可以是各种形式&#xff0c;可以…

项目管理基础知识

项目管理基础知识 导航 文章目录 项目管理基础知识导航一、项目相关概念二、时间管理三、人员管理四、风险管理 一、项目相关概念 项目定义的三层意思 一定的资源约束:时间资源、经费资源、人力资源一定的目标一次性任务 里程碑 是项目中的重要时点或事件持续时间为零&…

深度神经网络——什么是迁移学习?

1.概述 在练习机器学习时&#xff0c;训练模型可能需要很长时间。从头开始创建模型架构、训练模型&#xff0c;然后调整模型需要大量的时间和精力。训练机器学习模型的一种更有效的方法是使用已经定义的架构&#xff0c;可能具有已经计算出的权重。这是背后的主要思想 迁移学习…

makefile一些特殊且常用的符号

$^&#xff1a;表示所有的依赖文件列表&#xff0c;多个文件以空格分隔。 $&#xff1a;表示目标文件的名称。 $<&#xff1a;表示第一个依赖文件的名称。 $*&#xff1a;表示目标文件的主文件名&#xff08;不包括扩展名&#xff09;。 $?&#xff1a;表示所有比目标文件更…