openmp 分段错误 - 奇怪的行为

发布于 2024-11-25 07:10:04 字数 3498 浏览 1 评论 0原文

总的来说,我对 C++ 和 openmp 很陌生。我的程序的一部分在奇怪的情况下导致分段错误(至少对我来说很奇怪)。

使用g++编译器时不会出现这种情况,但使用intel编译器时会出现这种情况,但串行时没有错误。

在不同的系统(大学 HPC、英特尔编译器)上编译时也不会出现段错误,但在我的 PC 上却会出现段错误。

当存在三个特定的 cout 语句时,它也不会出现段错误,但是如果其中任何一个语句被注释掉,则会发生段错误。 (这就是我觉得奇怪的地方)

我是使用英特尔调试器(idb)的新手,我还不知道如何正确使用它。但我确实设法从中获取了这些信息:

Program received signal SIGSEGV
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996
996     moveWakePoints();

所以我将在下面展示 moveWakePoints 方法,并指出关键的 cout 行:

void VLMsolver::moveWakePoints() {

inFreeWakeStage =true;
int iw = 0;
std::vector<double> wV(3);
std::vector<double> bV(3);
for (int cl=0;cl<3;++cl) {
    wV[cl]=0;
    bV[cl]=0;
}

cout<<"thanks for helping"<<endl;

for (int b = 0;b < sNumberOfBlades;++b) {
    cout<<"b: "<<b<<endl;
    #pragma omp parallel for firstprivate(iw,b,bV,wV)
    for (int i = 0;i< iteration;++i) {
        iw = iteration -i - 1;
        for (int j = 0;j<numNodesY;++j) {
            cout<<"b: "<<b<<"a: "<<"a: "<<endl;
            double xp = wakes[b].x[iw*numNodesY+j];
            double yp = wakes[b].y[iw*numNodesY+j];
            double zp = wakes[b].z[iw*numNodesY+j];
            if ( (sFreeWake ==true && sFreezeAfter == 0) || ( sFreeWake==true && iw<((sFreezeAfter*2*M_PI)/(sTimeStep*sRotationRate)) && sRotationRate != 0  ) || ( sFreeWake==true && sRotationRate == 0 && iw<((sFreezeAfter*sChord)/(sTimeStep*sFreeStream)))) {
                if (iteration>1) { 
                    getWakeVelocity(xp, yp, zp, wV);
                }
                getBladeVelocity(xp, yp, zp, bV);
            } else {
                for (int cl=0;cl<3;++cl) {
                    wV[cl]=0;
                    bV[cl]=0;
                }
            }
            if (sRotationRate != 0) {
                double theta;
                theta = M_PI/2;
                double radius = sqrt(pow(yp,2) + pow(zp,2));
                wakes[b].yTemp[(iw+1)*numNodesY+j] = cos(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = sin(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + sFreeStream*sTimeStep;
            } else { 
                std::vector<double> fS(3);
                getFreeStreamVelocity(xp, yp, zp, fS);
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + fS[0] * sTimeStep;
                wakes[b].yTemp[(iw+1)*numNodesY+j] = yp + fS[1] * sTimeStep;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = zp + fS[2] * sTimeStep;
            }
            wakes[b].xTemp[(iw+1)*numNodesY+j] = wakes[b].xTemp[(iw+1)*numNodesY+j] + (wV[0]+bV[0])*sTimeStep;
            wakes[b].yTemp[(iw+1)*numNodesY+j] = wakes[b].yTemp[(iw+1)*numNodesY+j] + (wV[1]+bV[1])*sTimeStep;
            wakes[b].zTemp[(iw+1)*numNodesY+j] = wakes[b].zTemp[(iw+1)*numNodesY+j] + (wV[2]+bV[2])*sTimeStep;

        }  // along the numnodesy
    }  // along the iterations i
    if (sBladeSymmetry) {
        break;
    }
}

}

顶部的三个 cout 行是我添加的,并发现当我这样做时程序可以工作。

例如,在第三个 cout 行上,如果我将其更改为:

cout<<"b: "<<"a: "<<"a: "<<endl;

我会得到段错误,或者如果我将其更改为:

cout<<"b: "<<b<<endl; 

,我也会得到段错误。

感谢您的阅读,我很欣赏任何想法。

I'm quite new at c++ and openmp in general. I have a part of my program that is causing segmentation faults in strange circumstances (strange to me at least).

It doesn't occur when using the g++ compiler, but does with intel compiler, however there are no faults in serial.

It also doesnt segfault when compiling on a different system (university hpc, intel compiler), but does on my PC.

It also doesn't segfault when three particular cout statements are present, however if any one of them is commented out then the segfault occurs. (This is what I find strange)

I'm new at using the intel debugger (idb) and i don't know how to work it properly yet. But i did manage to get this information from it:

Program received signal SIGSEGV
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996
996     moveWakePoints();

So I'll show the moveWakePoints method below, and point out the critical cout lines:

void VLMsolver::moveWakePoints() {

inFreeWakeStage =true;
int iw = 0;
std::vector<double> wV(3);
std::vector<double> bV(3);
for (int cl=0;cl<3;++cl) {
    wV[cl]=0;
    bV[cl]=0;
}

cout<<"thanks for helping"<<endl;

for (int b = 0;b < sNumberOfBlades;++b) {
    cout<<"b: "<<b<<endl;
    #pragma omp parallel for firstprivate(iw,b,bV,wV)
    for (int i = 0;i< iteration;++i) {
        iw = iteration -i - 1;
        for (int j = 0;j<numNodesY;++j) {
            cout<<"b: "<<b<<"a: "<<"a: "<<endl;
            double xp = wakes[b].x[iw*numNodesY+j];
            double yp = wakes[b].y[iw*numNodesY+j];
            double zp = wakes[b].z[iw*numNodesY+j];
            if ( (sFreeWake ==true && sFreezeAfter == 0) || ( sFreeWake==true && iw<((sFreezeAfter*2*M_PI)/(sTimeStep*sRotationRate)) && sRotationRate != 0  ) || ( sFreeWake==true && sRotationRate == 0 && iw<((sFreezeAfter*sChord)/(sTimeStep*sFreeStream)))) {
                if (iteration>1) { 
                    getWakeVelocity(xp, yp, zp, wV);
                }
                getBladeVelocity(xp, yp, zp, bV);
            } else {
                for (int cl=0;cl<3;++cl) {
                    wV[cl]=0;
                    bV[cl]=0;
                }
            }
            if (sRotationRate != 0) {
                double theta;
                theta = M_PI/2;
                double radius = sqrt(pow(yp,2) + pow(zp,2));
                wakes[b].yTemp[(iw+1)*numNodesY+j] = cos(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = sin(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + sFreeStream*sTimeStep;
            } else { 
                std::vector<double> fS(3);
                getFreeStreamVelocity(xp, yp, zp, fS);
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + fS[0] * sTimeStep;
                wakes[b].yTemp[(iw+1)*numNodesY+j] = yp + fS[1] * sTimeStep;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = zp + fS[2] * sTimeStep;
            }
            wakes[b].xTemp[(iw+1)*numNodesY+j] = wakes[b].xTemp[(iw+1)*numNodesY+j] + (wV[0]+bV[0])*sTimeStep;
            wakes[b].yTemp[(iw+1)*numNodesY+j] = wakes[b].yTemp[(iw+1)*numNodesY+j] + (wV[1]+bV[1])*sTimeStep;
            wakes[b].zTemp[(iw+1)*numNodesY+j] = wakes[b].zTemp[(iw+1)*numNodesY+j] + (wV[2]+bV[2])*sTimeStep;

        }  // along the numnodesy
    }  // along the iterations i
    if (sBladeSymmetry) {
        break;
    }
}

}

The three cout lines at the top are what I added, and found the program worked when i did.

On the third cout line for example, if I change it to:

cout<<"b: "<<"a: "<<"a: "<<endl;

i get the segfault, or if I change it to:

cout<<"b: "<<b<<endl; 

, i also get the segfault.

Thanks for reading, I appreciate any ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

老子叫无熙 2024-12-02 07:10:04

正如前面的答案中已经指出的,您可以尝试使用 Valgrind 来检测内存损坏的位置。只需使用“-g -O0”编译二进制文件,然后运行:

valgrind --tool=memcheck --leak-check=full <binary> <arguments>

如果幸运的话,您将获得源代码中发生内存违规的确切行和列。

当添加一些“printf”语句时,段错误就会消失,这一事实确实并不奇怪。添加这些语句将修改程序拥有的内存部分。如果万一您在允许的内存部分内写入了错误的位置,则不会发生段错误。

您可以参考此 pdf(“调试技术/越界”部分)以获取对该主题的更广泛解释:

并行计算暑期学校

希望我能有所帮助:-)

As already stated in the previous answer you can try to use Valgrind to detect where your memory is corrupted. Just compile your binary with "-g -O0" and then run:

valgrind --tool=memcheck --leak-check=full <binary> <arguments>

If you are lucky you will get the exact line and column in the source code where the memory violation has occurred.

The fact that a segfault disappears when some "printf" statements are added is indeed not strange. Adding these statements you are modifying the portion of memory the program owns. If by any chance you are writing in a wrong location inside an allowed portion of memory, then the segfault will not occurr.

You can refer to this pdf (section "Debugging techniques/Out of Bounds") for a broader explanation of the topic:

Summer School of Parallel Computing

Hope I've been of help :-)

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