3.9.错误处理的理解以及错误的传播特性

目录

    • 前言
    • 1. thrust
    • 2. error
    • 总结

前言

杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。

本次课程学习精简 CUDA 教程-错误处理的理解以及错误的传播特性

课程大纲可看下面的思维导图

在这里插入图片描述

1. thrust

thrust 是一个基于 CUDA 的高级并行编程库,提供了一组易于使用的算法和数据结构,用于在 GPU 上进行并行计算。(form chatGPT)

thrust 提供了类似于标准 C++ 模板库(STL)的接口和语法,使开发者能够以一种简单直观的方式利用 GPU 的并行计算能力。它提供了丰富的算法,如排序、归约、扫描、变换等,并支持向量、数组和键值对等多种数据结构。

需要注意的是,thrust 并不是 CUDA 的一部分,而是一个由 NVIDIA 提供的独立库。要使用 thrust,需要将其包含在项目中,并确保正确链接和配置相关的编译器和构建系统。

在后续高性能的开发中,thrust 用的还是较少,但是了解它的存在还是很重要的

thrust 案例的示例代码如下:


#include <stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <iostream>
using namespace std;__host__ __device__
int sort_func(int a, int b){return a > b;
}int main(){int data[] = {5, 3, 1, 5, 2, 0};int ndata  = sizeof(data) / sizeof(data[0]);thrust::host_vector<int> array1(data, data + ndata);thrust::sort(array1.begin(), array1.end(), sort_func);thrust::device_vector<int> array2 = thrust::host_vector<int>(data, data + ndata);thrust::sort(array2.begin(), array2.end(), []__device__(int a, int b){return a < b;});printf("array1------------------------\n");for(int i = 0; i < array1.size(); ++i)cout << array1[i] << endl;printf("array2------------------------\n");for(int i = 0; i < array2.size(); ++i)cout << array2[i] << endl;return 0;
}

运行效果如下:

在这里插入图片描述

图1-1 thrust案例运行效果

通过 thrust 库,可以轻松地对数据进行排序操作。在这个示例中,thrust::sort() 函数被用来对数据进行排序,用户可以根据自己的需求定义排序函数或使用匿名函数来指定排序规则。这样,开发者可以更加便捷地利用 GPU 的并行计算能力进行高效的数据排序。

关于 thrust 的知识点有:(from 杜老师)

  1. thrust 是 cuda 开发的,基于 cuda 的 stl 库,便于使用
  2. 因为通常没用到 thrust,所以对这块儿也不做过多解释
  3. 对于 thrust 中的 lambda 表达式,需要增加 __device__ 标记表明函数可以被核函数调用,此时需要在 Makefile 中增加 --extended-lambda 标记
  4. 由于使用到了 device vector,因此编译环境需要修改为 nvcc 编译,因此 main.cpp 改成了 main.cu
  5. 内存的复制和分配已经被 cuda 封装了

2. error

关于 cuda 中的错误处理,你需要了解:

  1. 错误处理是理解如何控制 cuda 发生的错误和捕获错误的技术
  2. 在写 cuda 相关代码时,错误检查是错误处理的一种手段
  3. 在这里着重拿出来讲可恢复和不可恢复的错误,以及其传播的特性

error 案例的示例代码如下:


#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>
using namespace std;__global__ void func(float* ptr){int pos = blockIdx.x * blockDim.x + threadIdx.x;if(pos == 999){ptr[999] = 5;}
}int main(){float* ptr = nullptr;// 因为核函数是异步的,因此不会立即检查到他是否存在异常func<<<100, 10>>>(ptr);//func<<<100, 1050>>>(ptr);auto code1 = cudaPeekAtLastError();cout << cudaGetErrorString(code1) << endl;// 对当前设备的核函数进行同步,等待执行完毕,可以发现过程是否存在异常auto code2 = cudaDeviceSynchronize();cout << cudaGetErrorString(code2) << endl;// 异常会一直存在,以至于后续的函数都会失败float* new_ptr = nullptr;auto code3 = cudaMalloc(&new_ptr, 100);cout << cudaGetErrorString(code3) << endl;return 0;
}

运行效果如下:

在这里插入图片描述

图2-1 error案例运行效果

在这个示例中,我们展示了如何处理 CUDA 中的错误。通过调用 cudaPeekAtLastError(),我们可以立即检查最近的 CUDA 错误,而调用 cudaDeviceSynchronize() 则会等待当前设备的核函数执行完毕并检查是否有错误发生。这样,我们可以在程序中适时地处理和报告错误,避免错误在后续的函数调用中传播导致进一步的问题。

关于 error 的知识点有:(from 杜老师)

  1. 若 cuda 核函数出错,由于他是异步的,立即执行 cudaPeekAtLastError 只会拿到对输入参数校验是否正确的状态,而不会拿到核函数是否执行正确的状态
  2. 所以我们最开始是没有捕获到任何异常的
  3. 也因此需要等待核函数执行完毕后,才真的知道当前核函数是否出错,一般通过设备同步或者流同步进行等待
  4. 错误可分为可恢复和不可恢复两种:
  • 可恢复
  • 参数配置错误等,例如 block 越界(一般最大值是1024),shared memory 大小超出范围(一般是48KB)
  • 通过 cudaGetLastError 可以获取错误代码,同时把当前状态恢复为 success
  • 该错误在调用核函数后可以立即通过 cudaGetLastError/cudaPeekAtLastError 拿到
  • 该错误在下一个函数调用的时候会覆盖
  • 不可恢复
  • 核函数执行错误,例如访问越界等等异常
  • 该错误则会传递到之后的所有 cuda 操作上
  • 错误状态通常需要等到核函数执行完毕才能够拿到,也就是有可能在后续的任何流程中突然异常(因为是异步的)

总结

本次课程学习了 thrust 和错误处理,thrust 提供了类似于标准 C++ STL 库的接口和语法,你需要知道有这么一个东西的存在。错误检查在写 cuda 代码时非常重要,对于 cuda 中的错误可分为可恢复和不可恢复两种,在 cuda 程序出现问题时我们需要知道如何处理。

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

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

相关文章

【爬虫】5.4 Selenium 实现用户登录

目录 任务目标 创建模拟网站 创建服务器程序 键盘输入动作 鼠标点击动作 编写爬虫程序 任务目标 Selenium 查找的 HTML 元素是一个 WebElemen t对象&#xff0c; 这个对象不但可以获取元素的属性值&#xff0c;而且还能执行一 些键盘输入send_keys()与鼠标点击click()的动…

Qt画图框架,实现自己的画图框架

前面也讲到Qt提供画图框架&#xff0c;经典MVC模型&#xff0c;也没有什么问题。但Qt仅提供框架性东西&#xff0c;很难落地&#xff0c;很难应用在实际项目当中&#xff0c;一般需要自己捋一遍&#xff0c;这样才能理解好 什么view&#xff0c;canvas都好理解&#xff0c;只要…

Golang内存分配及垃圾回收

为什么需要垃圾回收&#xff1f; 自动释放不需要的对象&#xff0c;让出存储器资源&#xff0c;无需程序员手动执行 Go V1.3之前是标记-清除算法 具体步骤 缺点&#xff1a;程序卡顿、扫描整个heap、数据清除会产生heap碎片 V1.3之后&#xff0c;做了简单的优化 V1.5之后&a…

MySQL索引、事务、与存储引擎

MySQL索引、事务、与存储引擎 一、索引 1.概念 索引是一个排序的列表&#xff0c;包含索引字段的值和其相对应的行数据所在的物理地址2.作用 优点 加快表的查询速度 可以对字段排序缺点 额外占用磁盘空间 更新包含索引的表效率会更慢3.索引工作模式 没有索引的情况下&am…

-1在内存中的存储及打印问题。

首先先看看代码&#xff1a; #include"stdio.h" int main() { char a -1; signed char b -1; unsigned char c -1; printf("a%d b%d c%d", a, b, c); return 0; } 代码很简单&#xff0c;问打印结果是什么&#xff1f; 下面我…

一文了解Python字符串格式化、input语句

目录 &#x1f969;1.1.字符串拼接 &#x1f969;1.2.对字符串格式化 &#x1f969;1.3.字符串精度 &#x1f969;1.4.快速格式化 &#x1f969;1.5.对表达式格式化 &#x1f969;1.6.黑马小练习 &#x1f969;2.1.input语句 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客…

【前端知识】React 基础巩固(十八)——组件化开发(二)

React 基础巩固(十八)——组件化开发&#xff08;二&#xff09; 生命周期 生命周期是一个抽象的概念&#xff0c;在生命周期的整个过程中&#xff0c;分成了很多个阶段 比如装载阶段&#xff08;Mount&#xff09;&#xff0c;组件第一次在 DOM 树中被渲染的过程比如更新过程…

【python】逻辑中断(and or)

今天学习javascript的时候竟然有一个额外收获&#xff1a;逻辑中断。而且我实验了一下&#xff0c;逻辑中断同样适用于python。 0 and 2返回&#xff1a; 0 1 and 2返回&#xff1a; 2 0 and 2返回的是0&#xff0c;而1 and 2返回的是2。就是因为在0那里出现了逻辑中断。 解…

大模型的数据瓶颈应该如何破除?看完这篇文章你就懂了

随着机器学习和深度学习技术的不断发展&#xff0c;大模型已经成为了现代人工智能研究和应用中的重要组成部分。然而&#xff0c;对于大模型而言&#xff0c;数据瓶颈问题仍然是一个亟待解决的挑战。尤其是在数据存量和质量方面&#xff0c;我们需要更加注重其影响&#xff0c;…

【Gradle】Gradle的概述与简单使用

一、概述 1.什么是Gradle&#xff1f; Gradle 是一种构建工具。 Java世界中主要有三大构建工具&#xff1a;Ant、Maven和Gradle。Ant几乎销声匿迹了&#xff0c;常见的就只有Maven和Gradle。 目前市面上Java开发&#xff0c;使用的构建工具基本都是Maven&#xff1b;安卓开…

C语言程序设计——数据在内存中的存储

一、数据类型介绍 1.基本内置类型 char // 字符数据类型 1 B short // 短整型 2 B int // 整型 4 B long // 长整型 4 or 8 B long long //更长的整型 8 B float //单精度浮点型 4 B double //双精…

解决Unity的PostProcess奇怪报错

大家好&#xff0c;我是阿赵。   最近在使用Unity的PostProcess后处理效果的时候&#xff0c;发现了一个问题&#xff0c;下面记录一下这个问题的出现原因和解决办法。 一、出现问题 问题是这样出现的&#xff1a;   在场景里面添加某一个后处理效果后&#xff0c;当这个后…