使用OpenMP并行化后Valgrind检测到内存泄漏,是否存在认知误区?
问题:OpenMP并行循环导致Valgrind检测到“可能丢失”的内存?
以下是我编写的C++代码:
#include <iostream> #include <random> int main() { int a; int *arr; a = 3; arr = new int[a]; #pragma omp parallel for for (int i = 0; i < a; i++) arr[i] = i; delete[] arr; return 0; }
使用Valgrind测试这段代码时,得到如下输出:
==2606== HEAP SUMMARY: ==2606== in use at exit: 3,360 bytes in 7 blocks ==2606== total heap usage: 10 allocs, 3 frees, 108,892 bytes allocated ==2606== ==2606== LEAK SUMMARY: ==2606== definitely lost: 0 bytes in 0 blocks ==2606== indirectly lost: 0 bytes in 0 blocks ==2606== possibly lost: 912 bytes in 3 blocks ==2606== still reachable: 2,448 bytes in 4 blocks ==2606== suppressed: 0 bytes in 0 blocks
移除#pragma omp parallel for指令后,Valgrind检测无任何问题。我是否对OpenMP或内存分配的使用存在误解?
更新:使用--leak-check-full参数后的Valgrind输出如下:
==2682== 912 bytes in 3 blocks are possibly lost in loss record 4 of 5 ==2682== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==2682== by 0x40149DA: allocate_dtv (dl-tls.c:286) ==2682== by 0x40149DA: _dl_allocate_tls (dl-tls.c:532) ==2682== by 0x4DE4322: allocate_stack (allocatestack.c:622) ==2682== by 0x4DE4322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660) ==2682== by 0x4A4FDEA: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) ==2682== by 0x4A478E0: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) ==2682== by 0x109184: main (main.cpp:10)
解答
这些被标记为“可能丢失”的内存并非你的代码问题,而是OpenMP运行时库(libgomp)在创建线程时分配的**线程本地存储(TLS)**相关资源。
从调用栈可以清晰看到:内存是在pthread_create创建线程时,由glibc分配的TLS结构。OpenMP运行时会负责管理这些线程资源,但程序退出时,部分线程资源的释放逻辑可能发生在Valgrind的内存泄漏检测流程之后,或者Valgrind无法识别libgomp内部的内存管理机制,因此误报为“可能丢失”。
你的代码本身不存在内存泄漏:你手动分配的arr已经通过delete[]正确释放,移除OpenMP指令后Valgrind检测无问题也能证明这一点。
如果想消除这类误报,可以使用Valgrind的--suppressions参数加载针对OpenMP的抑制文件,多数Linux发行版会提供现成的抑制文件(比如/usr/share/valgrind/openmp.supp),也可以自行编写规则忽略libgomp相关的内存分配记录。
内容的提问来源于stack exchange,提问作者Mingi Kim
相关产品推荐
相关产品推荐

