valgrind 和 openmp 仍然可以访问,但可能会丢失,这很糟糕吗?
这里是c++新手。
在过去的几天里,我一直在提高我的内存管理技能,并且根据 valgrind 的说法,我的程序不再泄漏内存。事实上,我根本没有收到来自 valgrind 的警告。
但是,当我将 openmp 循环添加到代码中时,我开始在 valgrind (memcheck) 中出现以下错误:(但没有明确丢失的块)
==6417== 304 bytes in 1 blocks are possibly lost in loss record 3 of 4
==6417== at 0x4C279FC: calloc (vg_replace_malloc.c:467)
==6417== by 0x4011868: _dl_allocate_tls (dl-tls.c:300)
==6417== by 0x6649871: pthread_create@@GLIBC_2.2.5 (allocatestack.c:570)
==6417== by 0x62263DF: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x42A2BB: Blade::updatePanels() (blade.cpp:187)
==6417== by 0x418677: VLMsolver::initialiseBlade() (vlmsolver.cpp:590)
==6417== by 0x415A1B: VLMsolver::start(std::string) (vlmsolver.cpp:80)
==6417== by 0x40B28C: main (charybdis.cpp:176)
并且:
==6417== 1,568 bytes in 1 blocks are still reachable in loss record 4 of 4
==6417== at 0x4C28FAC: malloc (vg_replace_malloc.c:236)
==6417== by 0x6221578: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x6226044: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x622509B: GOMP_parallel_start (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x41AF58: VLMsolver::segmentCirculations() (vlmsolver.cpp:943)
==6417== by 0x415E4B: VLMsolver::solveManager() (vlmsolver.cpp:177)
==6417== by 0x415A4B: VLMsolver::start(std::string) (vlmsolver.cpp:91)
==6417== by 0x40B28C: main (charybdis.cpp:176)
这是 valgrind 不理解 openmp 的情况吗?或者它可能会变得险恶?
请注意,当我使用 helgrind 运行 valgrind 时,我收到数千条“读取期间可能发生数据争用”(和写入)消息。然而,我的程序(流体动力学求解器)对于 openmp 和串行代码给出了相同的结果。如果您对此问题感兴趣,我可以提供 helgrind 错误和相关部分。
否则现在,这是第二条消息的有问题的代码:第 943 行是 pragma 行。
for (int b = 0;b < sNumberOfBlades;++b) {
*VLMSOLVER.CPP LINE 943 is next*:
#pragma omp parallel for collapse(2) num_threads(2) firstprivate(b)
for (int i = 0;i<numX;++i) {
for (int j = 0;j<numY;++j) {
if (j == 0) {
blades[b].line[i*numNodesY+j].circulation = blades[b].panel[i*numY+j].circulation;
} else {
blades[b].line[i*numNodesY+j].circulation = blades[b].panel[i*numY+j].circulation - blades[b].panel[i*numY+j-1].circulation;
}
if (j==numY-1) {
blades[b].line[i*numNodesY+j+1].circulation = -1 * blades[b].panel[i*numY+j].circulation;
}
}
}
if (sBladeSymmetry) {
break;
}
}
int k = numX*numNodesY;
for (int b = 0;b < sNumberOfBlades;++b) {
for (int i = 0;i<numX;++i) {
for (int j = 0;j<numY;++j) {
if (i == 0) {
blades[b].line[k+i*numY+j].circulation = - 1 * blades[b].panel[i*numY+j].circulation;
} else {
blades[b].line[k+i*numY+j].circulation = -1 * blades[b].panel[i*numY+j].circulation + blades[b].panel[(i-1)*numY+j].circulation;
}
if (i==numX-1) {
blades[b].line[k+(i+1)*numY+j].circulation = blades[b].panel[i*numY+j].circulation;
}
}
}
if (sBladeSymmetry) {
break;
}
}
c++ newbie here.
I've been improving my memory management skills over the last few days, and my program no longer leaks memory according to valgrind. In fact, I get no warnings from valgrind at all.
However, when I add openmp loops into my code, I start to get the following errors in valgrind (memcheck): (but no definitely lost blocks)
==6417== 304 bytes in 1 blocks are possibly lost in loss record 3 of 4
==6417== at 0x4C279FC: calloc (vg_replace_malloc.c:467)
==6417== by 0x4011868: _dl_allocate_tls (dl-tls.c:300)
==6417== by 0x6649871: pthread_create@@GLIBC_2.2.5 (allocatestack.c:570)
==6417== by 0x62263DF: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x42A2BB: Blade::updatePanels() (blade.cpp:187)
==6417== by 0x418677: VLMsolver::initialiseBlade() (vlmsolver.cpp:590)
==6417== by 0x415A1B: VLMsolver::start(std::string) (vlmsolver.cpp:80)
==6417== by 0x40B28C: main (charybdis.cpp:176)
and:
==6417== 1,568 bytes in 1 blocks are still reachable in loss record 4 of 4
==6417== at 0x4C28FAC: malloc (vg_replace_malloc.c:236)
==6417== by 0x6221578: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x6226044: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x622509B: GOMP_parallel_start (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6417== by 0x41AF58: VLMsolver::segmentCirculations() (vlmsolver.cpp:943)
==6417== by 0x415E4B: VLMsolver::solveManager() (vlmsolver.cpp:177)
==6417== by 0x415A4B: VLMsolver::start(std::string) (vlmsolver.cpp:91)
==6417== by 0x40B28C: main (charybdis.cpp:176)
Is this a case of valgrind not understanding the openmp? Or is it something that might become sinister?
Note that when I run valgrind with helgrind, I get thousands of "possible data race during read" (and write) messages. However my program (a fluid dynamics solver) gives the same results for both the openmp and serial codes. I can provide the helgrind errors and relevant sections if you are interested in that for this problem.
Otherwise for now, here is the offending code for the second message: and line 943 is the pragma line.
for (int b = 0;b < sNumberOfBlades;++b) {
*VLMSOLVER.CPP LINE 943 is next*:
#pragma omp parallel for collapse(2) num_threads(2) firstprivate(b)
for (int i = 0;i<numX;++i) {
for (int j = 0;j<numY;++j) {
if (j == 0) {
blades[b].line[i*numNodesY+j].circulation = blades[b].panel[i*numY+j].circulation;
} else {
blades[b].line[i*numNodesY+j].circulation = blades[b].panel[i*numY+j].circulation - blades[b].panel[i*numY+j-1].circulation;
}
if (j==numY-1) {
blades[b].line[i*numNodesY+j+1].circulation = -1 * blades[b].panel[i*numY+j].circulation;
}
}
}
if (sBladeSymmetry) {
break;
}
}
int k = numX*numNodesY;
for (int b = 0;b < sNumberOfBlades;++b) {
for (int i = 0;i<numX;++i) {
for (int j = 0;j<numY;++j) {
if (i == 0) {
blades[b].line[k+i*numY+j].circulation = - 1 * blades[b].panel[i*numY+j].circulation;
} else {
blades[b].line[k+i*numY+j].circulation = -1 * blades[b].panel[i*numY+j].circulation + blades[b].panel[(i-1)*numY+j].circulation;
}
if (i==numX-1) {
blades[b].line[k+(i+1)*numY+j].circulation = blades[b].panel[i*numY+j].circulation;
}
}
}
if (sBladeSymmetry) {
break;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Stillreachable
是不是内存泄漏。Stillreachable
表示内存块尚未被释放,但仍然存在指向起始位置的有效指针寄存器或内存中尚未释放的该块的信息。您需要查看Valgrind 常见问题解答。解释了
libgomp
导致警告的实际原因这里。Still reachable
is not a memory leak.Still reachable
means that a block of memory has not been freed but there are still valid pointers to the start of that block in registers or memory that has not been freed.You need to have a look at the Valgrind FAQ. The actual reason for
libgomp
causing the warning is explained here.