valgrind 和 openmp 仍然可以访问,但可能会丢失,这很糟糕吗?

发布于 2024-11-28 02:36:08 字数 3174 浏览 1 评论 0原文

这里是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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨小沫ゞ 2024-12-05 02:36:09

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文