OpenCL clCreateContextFromType函数会导致内存泄漏

时间:2020-04-07 23:30:07

标签: performance debugging memory-leaks opencl valgrind

我对我的一个开源OpenCL代码(https://github.com/fangq/mmc)运行了valgrind,它检测到OpenCL host code中有很多内存泄漏。其中大多数指向the line,其中我使用clCreateContextFromType创建了上下文对象。

我仔细检查了我所有的OpenCL变量,命令队列,内核和程序,并确保它们are all properly released,但是,在对示例程序进行测试时,每次对mmc_run_cl() function的调用都会增加内存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设备上运行-G 1输入,请将其更改为其他数字(将-L添加到列表中)。

在下表中,我列出了在装有最新驱动程序+ cuda 9的Linux盒(Ubuntu 16.04)上的NVIDIA GPU(TitanV)上,每个valgrind检测到的泄漏的重复计数。

同样,大多数泄漏与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配置文件in this post

enter image description here

我将针对如何使用NVIDIA OpenCL减少这种内存泄漏提出一个新的问题和悬赏。如果您有任何经验,请分享。将在下面发布链接。谢谢

1 个答案:

答案 0 :(得分:1)

我仔细检查了所有的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手册中所述生成禁止文件:https://valgrind.org/docs/manual/manual-core.html#manual-core.suppress

...,但是仍然在对示例程序进行测试时,每次调用 mmc_run_cl()函数将内存增加300MB-400MB,并且不会释放 返回时

您如何检查的?我还没有看到可疑的内存增长。我设置了-n 1000e4,使其运行了大约2分钟,其中分配的内存一直保持在RAM大小的〜0.6%左右。请注意,在Intel GPU和CPU上我没有使用nvidia CUDA,而是使用POCL,并与从Ubuntu 18.04上的libOpenCL软件包安装的ocl-icd-libopencl1:amd64链接。因此,您可以尝试一下,检查是否有任何改变。

========更新============================= >

我已按照注释中的描述重新运行它,第一次迭代后内存使用率为0.6%,然后在第二次迭代后内存使用率增加为0.9%,此后下一次迭代并没有增加内存使用率。除了我之前观察到的内容外,Valgrind也没有报告任何新内容。因此,我建议使用不同于nvidia-cuda的libOpenCL进行链接并重新测试。