关于错误使用cudaDeviceReset()函数,导致多线程下cuda错误、进程崩溃的问题

1、问题描述

在项目迭代优化的一个版本里,突然爆出以下问题:
某程序开辟了多个线程,每个线程分别执行模型加载、读离线视频及视频帧模型推理、模型卸载以上操作。
在程序执行了一段时间后,必现地随机报cuda的某个函数执行错误,如cudaMalloc函数执行错误、cudaStreamSynchronize函数执行错误等,并且每次报错的线程也随机,很难定位是具体哪个线程内的代码问题(备注:每个线程对应一个场景任务,其代码都不一样,如人脸检测、异常行为检测等)。
在这里插入图片描述

2、问题分析

因为每次报错,报错线程随机(即对应是哪个场景算法随机)、且每次报错具体内容不一样,所以不能通过gdb直接定位出代码问题行,所以正面刚无果。
下面迂回定位问题:
由于之前的版本没问题,那就从当前版本里找做了哪些改动、且是cuda相关的改动(因为每次都是cuda错误)。经过对相关改动代码进行不断注释、运行;再注释、再运行,最后找到问题。

3、最终问题定位与解决

cudaDeviceReset()函数错误调用。
该问题版本里,为了释放cuda资源,在卸载函数里加入了cudaDeviceReset()函数;但是经过细查发现,该函数使用时,会销毁当前进程中当前设备上的所有分配并重置所有状态
即我的程序进入到卸载接口时,调用cudaDeviceReset函数,销毁了本进程中所有线程在对应GPU设备上的资源分配与状态,所以下一时刻,本不该结束的线程,无论是哪个在使用该GPU设备,统统报错、且是cuda的任一错误!
注释该函数后,问题解决。

4、cuda知识学习

吃了cuda不熟悉的亏,下面摘抄cuda官方指导手册里,关于cudaDeviceReset和内存释放的一些描述:

  • 关于cudaDeviceReset()的函数声明

host_ ​cudaError_t cudaDeviceReset ( void )
Destroy all allocations and reset all state on the current device in the current process.

  • 关于cudaDeviceReset()被调用时的具体操作

When a host thread calls cudaDeviceReset(), this destroys the primary context of the device the host thread currently operates on (i.e., the current device as defined in Device Selection). The next runtime function call made by any host thread that has this device as current will create a new primary context for this device.

  • 关于调用cudaDeviceReset()来释放内存

The memcheck tool can detect leaks of allocated memory.

Memory leaks are device side allocations that have not been freed by the time the context is destroyed. The memcheck tool tracks device memory allocations created using the CUDA driver or runtime APIs. Starting in CUDA 5, allocations that are created dynamically on the device heap by calling malloc() inside a kernel are also tracked.

For an accurate leak checking summary to be generated, the application’s CUDA context must be destroyed at the end. This can be done explicitly by calling cuCtxDestroy() in applications using the CUDA driver API, or by calling cudaDeviceReset() in applications programmed against the CUDA run time API.

The --leak-check full option must be specified to enable leak checking.

官方意思应该是,的确需要通过cuCtxDestroy或cudaDeviceReset对cuda申请的资源(CUDA contex)进行释放。
但是通过本篇出现的错误总结:在不熟悉cuda的情况下,释放cuda资源时、尤其是进行reset操作时,要注意释放时机;例如,可以在整个进程结束的时候,对cuda进行reset,毕竟GPU和CPU执行程序是异步的,且根据目前了解发现,不少cuda函数或工具,对gpu操作时、是直接对整块GPU操作、而不是其中的某“线程”。

参考链接:cuda官方指导手册

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值