Eigen + std::vector + OpenMP 内存泄漏
Memory leak with Eigen + std::vector + OpenMP
我对 Eigen 有一个问题,这让我发疯。每当我尝试重新分配一组存储在 std::vector.
中的 Eigen::MatrixXd 时,我总是从 valgrind 获取内存泄漏
我至少重写了 5 次我的代码,我已经尝试使用 std::maps(这是我最初解决方案的一部分),我已经从向量的向量转移到普通向量... . 没有任何效果。一旦我添加了我的 openMP 指令,我就得到了泄漏。
这是一个最小的工作示例:
#include <iostream>
#include <Eigen/Dense>
#include <vector>
#include <omp.h>
typedef Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EMat;
EMat function() {
EMat a(19,29);
return a;
}
int main() {
std::vector < EMat > v(10);
#pragma omp parallel for schedule(dynamic)
for (unsigned int i = 0; i < 10; ++i) {
v[i] = function();
}
}
如果我尝试使用 valgrind 运行 它,我得到:
r@darkstar ~/tmp $ valgrind --leak-check=full --show-leak-kinds=all ./test_leak==9640== Memcheck, a memory error detector
==9640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9640== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9640== Command: ./test_leak
==9640==
==9640==
==9640== HEAP SUMMARY:
==9640== in use at exit: 4,632 bytes in 10 blocks
==9640== total heap usage: 31 allocs, 21 frees, 48,952 bytes allocated
==9640==
==9640== 72 bytes in 1 blocks are still reachable in loss record 1 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7F8: gomp_realloc (alloc.c:54)
==9640== by 0x51439FA: gomp_team_start (team.c:376)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 192 bytes in 1 blocks are still reachable in loss record 2 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640== by 0x5143B8E: gomp_team_start (team.c:190)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 2,128 bytes in 7 blocks are possibly lost in loss record 3 of 4
==9640== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==9640== by 0x5C33DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==9640== by 0x5143905: gomp_team_start (team.c:439)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 2,240 bytes in 1 blocks are still reachable in loss record 4 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640== by 0x51434D5: gomp_new_team (team.c:144)
==9640== by 0x51405FC: gomp_parallel_loop_start (loop.c:447)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== LEAK SUMMARY:
==9640== definitely lost: 0 bytes in 0 blocks
==9640== indirectly lost: 0 bytes in 0 blocks
==9640== possibly lost: 2,128 bytes in 7 blocks
==9640== still reachable: 2,504 bytes in 3 blocks
==9640== suppressed: 0 bytes in 0 blocks
==9640==
==9640== For counts of detected and suppressed errors, rerun with: -v
==9640== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我花了几个小时在网上搜索和试验,但没有成功。
谁能帮帮我?
提前致谢!
R
这不是因为 Eigen 也不是 std::vector
,而是因为 OpenMP "leaks" 或者更确切地说,valgrind 报告不是 "trustable"。
如前所述,不要在这上面花太多时间,您不对这些泄漏负责。
查看相关链接:
- does openmp allocate memory and free all after
As far as I can tell libgomp does not kill it's spawned threads at the end of execution and makes the kernel clean up do this.
In libgomp case, most of the allocations still reachable at exit time
fall into the category where they really can't be freed.
我对 Eigen 有一个问题,这让我发疯。每当我尝试重新分配一组存储在 std::vector.
中的 Eigen::MatrixXd 时,我总是从 valgrind 获取内存泄漏我至少重写了 5 次我的代码,我已经尝试使用 std::maps(这是我最初解决方案的一部分),我已经从向量的向量转移到普通向量... . 没有任何效果。一旦我添加了我的 openMP 指令,我就得到了泄漏。
这是一个最小的工作示例:
#include <iostream>
#include <Eigen/Dense>
#include <vector>
#include <omp.h>
typedef Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EMat;
EMat function() {
EMat a(19,29);
return a;
}
int main() {
std::vector < EMat > v(10);
#pragma omp parallel for schedule(dynamic)
for (unsigned int i = 0; i < 10; ++i) {
v[i] = function();
}
}
如果我尝试使用 valgrind 运行 它,我得到:
r@darkstar ~/tmp $ valgrind --leak-check=full --show-leak-kinds=all ./test_leak==9640== Memcheck, a memory error detector
==9640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9640== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9640== Command: ./test_leak
==9640==
==9640==
==9640== HEAP SUMMARY:
==9640== in use at exit: 4,632 bytes in 10 blocks
==9640== total heap usage: 31 allocs, 21 frees, 48,952 bytes allocated
==9640==
==9640== 72 bytes in 1 blocks are still reachable in loss record 1 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7F8: gomp_realloc (alloc.c:54)
==9640== by 0x51439FA: gomp_team_start (team.c:376)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 192 bytes in 1 blocks are still reachable in loss record 2 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640== by 0x5143B8E: gomp_team_start (team.c:190)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 2,128 bytes in 7 blocks are possibly lost in loss record 3 of 4
==9640== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==9640== by 0x5C33DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==9640== by 0x5143905: gomp_team_start (team.c:439)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== 2,240 bytes in 1 blocks are still reachable in loss record 4 of 4
==9640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640== by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640== by 0x51434D5: gomp_new_team (team.c:144)
==9640== by 0x51405FC: gomp_parallel_loop_start (loop.c:447)
==9640== by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640== by 0x400EBD: main (test_leak.cpp:19)
==9640==
==9640== LEAK SUMMARY:
==9640== definitely lost: 0 bytes in 0 blocks
==9640== indirectly lost: 0 bytes in 0 blocks
==9640== possibly lost: 2,128 bytes in 7 blocks
==9640== still reachable: 2,504 bytes in 3 blocks
==9640== suppressed: 0 bytes in 0 blocks
==9640==
==9640== For counts of detected and suppressed errors, rerun with: -v
==9640== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我花了几个小时在网上搜索和试验,但没有成功。 谁能帮帮我?
提前致谢!
R
这不是因为 Eigen 也不是 std::vector
,而是因为 OpenMP "leaks" 或者更确切地说,valgrind 报告不是 "trustable"。
如前所述,不要在这上面花太多时间,您不对这些泄漏负责。
查看相关链接:
- does openmp allocate memory and free all after
As far as I can tell libgomp does not kill it's spawned threads at the end of execution and makes the kernel clean up do this.
In libgomp case, most of the allocations still reachable at exit time fall into the category where they really can't be freed.