Performance OpenCL clCreateContextFromType函数导致内存泄漏

Performance OpenCL clCreateContextFromType函数导致内存泄漏,performance,debugging,memory-leaks,opencl,valgrind,Performance,Debugging,Memory Leaks,Opencl,Valgrind,我对我的一个开源OpenCL代码()运行了valgrind,它检测到了内存中的大量内存泄漏。大多数都指向我使用clCreateContextFromType创建上下文对象的地方 我仔细检查了我所有的OpenCL变量、命令队列、内核和程序,并确保它们是正确的,但在对示例程序进行测试时,每次调用都会将内存增加300MB-400MB,并且不会在返回时释放 通过在终端中运行以下命令,可以复制valgrind报告: git clone https://github.com/fangq/mmc.git cd

我对我的一个开源OpenCL代码()运行了
valgrind
,它检测到了内存中的大量内存泄漏。大多数都指向我使用
clCreateContextFromType
创建上下文对象的地方

我仔细检查了我所有的OpenCL变量、命令队列、内核和程序,并确保它们是正确的,但在对示例程序进行测试时,每次调用都会将内存增加300MB-400MB,并且不会在返回时释放

通过在终端中运行以下命令,可以复制valgrind报告:

git clone https://github.com/fangq/mmc.git
cd mmc/src
make clean
make all
cd ../examples/validation
valgrind --show-leak-kinds=all --leak-check=full ../../src/bin/mmc -f cube2.inp -G 1 -s cube2 -n 1e4 -b 0 -D TP -M G -F bin
假设您的系统安装了gcc/git/libOpenCL和valgrind。如果要在其他OpenCL设备上运行,请将
-g1
输入更改为其他数字(将
-L
添加到列表)

在下表中,我列出了valgrind使用最新的驱动程序+cuda 9在Linux设备(Ubuntu 16.04)上的NVIDIA GPU(TitanV)上检测到的每个漏洞的重复计数

同样,大多数泄漏都与
clCreateContextFromType
行有关,我假设一些GPU内存没有释放,但我确实在主机代码末尾释放了所有GPU资源

你注意到我在主机代码中遗漏了什么吗?非常感谢你的意见

counts |        error message
------------------------------------------------------------------------------------
    380 ==27828==    by 0x402C77: main (mmc.c:67)
Code: entry point to the below errors

     64 ==27828==    by 0x41CF02: mcx_list_gpu (mmc_cl_utils.c:135)
Code: OCL_ASSERT((clGetPlatformIDs(0, NULL, &numPlatforms)));

      4 ==27828==    by 0x41D032: mcx_list_gpu (mmc_cl_utils.c:154)
Code: context=clCreateContextFromType(cps,devtype[j],NULL,NULL,&status);

     58 ==27828==    by 0x41DF8A: mmc_run_cl (mmc_cl_host.c:111)
Code: entry point to the below errors

    438 ==27828==    by 0x41E006: mmc_run_cl (mmc_cl_host.c:124)
Code: OCL_ASSERT(((mcxcontext=clCreateContextFromType(cprops,CL_DEVICE_TYPE_ALL,...));

     13 ==27828==    by 0x41E238: mmc_run_cl (mmc_cl_host.c:144)
Code: OCL_ASSERT(((mcxqueue[i]=clCreateCommandQueue(mcxcontext,devices[i],prop,&status),status)));

      1 ==27828==    by 0x41E7A6: mmc_run_cl (mmc_cl_host.c:224)
Code:  OCL_ASSERT(((gprogress[0]=clCreateBufferNV(mcxcontext,CL_MEM_READ_WRITE, NV_PIN, ...);

      1 ==27828==    by 0x41E7F9: mmc_run_cl (mmc_cl_host.c:225)
Code: progress = (cl_uint *)clEnqueueMapBuffer(mcxqueue[0], gprogress[0], CL_TRUE, ...);

     10 ==27828==    by 0x41EDFA: mmc_run_cl (mmc_cl_host.c:290)
Code: status=clBuildProgram(mcxprogram, 0, NULL, opt, NULL, NULL);

      7 ==27828==    by 0x41F95C: mmc_run_cl (mmc_cl_host.c:417)
Code: OCL_ASSERT((clEnqueueReadBuffer(mcxqueue[devid],greporter[devid],CL_TRUE,0,...));
更新[04/11/2020]:

阅读@doqtor的评论,我在5个不同的设备上做了以下测试,2个NVIDIA GPU,2个AMD GPU和1个Intel CPU。他所说的是正确的-内存泄漏不会发生在英特尔OpenCL库上,我还发现AMD OpenCL驱动程序也很好。唯一的问题是NVIDIA OpenCL库似乎在我测试的两个GPU(Titan V和RTX2080)上都存在泄漏

我的测试结果如下。介绍了使用psrecord进行内存/CPU评测

关于如何使用NVIDIA OpenCL减少内存泄漏,我将提出一个新的问题和奖励。如果你有这方面的经验,请分享。将在下面发布链接。谢谢

我仔细检查了所有OpenCL变量、命令队列、内核和 程序,并确保它们都已正确发布

我仍然在mmc代码中发现了一个(微小的)内存泄漏:

==15320== 8 bytes in 1 blocks are definitely lost in loss record 14 of 1,905
==15320==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15320==    by 0x128D48: mmc_run_cl (mmc_cl_host.c:137)
==15320==    by 0x11E71E: main (mmc.c:67)
未释放由
greporter
分配的内存。那就由你来解决

其余的是OpenCL库中潜在的内存泄漏。它们可能是内存泄漏,也可能不是内存泄漏,例如库可能使用自定义内存分配器,
valgrind
无法识别或执行其他一些技巧。这方面有很多线索:

一般来说,除非您想深入研究库代码并对此做些什么,否则您无法对此做太多工作。 我建议小心地压制那些来自图书馆的报道。可以按照valgrind手册中的说明生成抑制文件:

。。。但是,在对示例程序进行测试时,对 mmc_run_cl()函数会将内存增加300MB-400MB,并且不会释放 作为回报

你怎么查到的?我没有看到记忆可疑地增长。我设置了
-n1000e4
,它运行了2分钟,分配的内存一直保持静止,大约是我RAM大小的0.6%。请注意,我没有在英特尔GPU和CPU上使用
nvidia CUDA
,而是使用
POCL
,并链接到从Ubuntu 18.04上的
ocl-icd-LIBONCL1:amd64
软件包安装的
libOpenCL
。所以你可以试着试试,看看这是否改变了什么

====================================================


我已经按照您在评论中描述的那样重新运行了它,在第一次迭代之后,内存使用率为0.6%,在第二次迭代之后,内存使用率增加到0.9%,之后,下一次迭代没有增加内存使用率。Valgrind也没有报告任何新的东西,除了我之前观察到的。因此,我建议与不同于nvidia cuda LIBONECL的软件进行链接并重新测试。

您是否尝试过使用复制您的问题?您是否尝试过上面的6命令示例?我无法编译这些内容。。。问题是,如果你用最小的可重复的例子来再现你的问题?首先,我考虑我的6个命令示例代码最小可重复的例子-因为这个报告的行为发生在当前的代码库中,并且你可以用我的命令来复制它。如果你不能编译,你可以从我认为@doqtor的意思可能是:你有没有尝试过删除你的代码片段来缩小当问题没有发生时的范围?也许这个网站上的某个人有时间阅读并完全理解你的500LOC功能,但是如果你发布了一段显示相同问题的代码,那么你就更有可能得到帮助。谢谢@doqtor的评论。关于格雷波特,是的,你是对的。我在调试过程中发现了这一点:请看。在多次运行模拟时,我在matlab mex文件中观察到内存泄漏。要在二进制文件中重现此信息,可以打开
mmc.c
,插入(i i=0;谢谢。我更新了我原来的问题,确认英特尔和AMD OpenCL没有内存泄漏,但它确实出现在英伟达GPU上。我将为您提供一个新的赏金/问题,具体说是如何减少NVIDIA内存泄漏,如果您有经验,欢迎分享!谢谢您在这里发布我的后续问题: