如何在使用OpenMP并行化for循环时修复[Segmentation fault]?

时间:2018-05-15 16:43:09

标签: for-loop parallel-processing segmentation-fault openmp

我尝试并行化for循环时出现分段错误,我无法理解原因。

以下是代码:

#pragma omp parallel for schedule(static) reduction(+:ptx,pty)
    for(int i=0;i<numSteps;i++)
    {
        float energy=0;
        for(int idx=0;idx<patternNum;idx++)
        {
            float hitColor = getInterpolatedElement31(frame->dI,
                                        (float)(ptx+rotatetPattern[idx][0]),
                                        (float)(pty+rotatetPattern[idx][1]),
                                        wG[0]);

            if(!std::isfinite(hitColor)) {energy+=1e5; continue;}

            float residual = hitColor - (float)(hostToFrame_affine[0] * color[idx] + hostToFrame_affine[1]);
            float hw = fabs(residual) < setting_huberTH ? 1 : setting_huberTH / fabs(residual);
            energy += hw *residual*residual*(2-hw);
        }

        if(debugPrint)
            printf("step %.1f %.1f (id %f): energy = %f!\n",
                    ptx, pty, 0.0f, energy);

        errors[i] = energy;
        if(energy < bestEnergy)
        {
            bestU = ptx; bestV = pty; bestEnergy = energy; bestIdx = i;
        }

        ptx+=dx;
        pty+=dy;
    }
std::cout << "hello\n";

for - 循环所在的函数被多次调用,并且分段错误仅在此函数的多次迭代后 >后引起。

这就是我放cout << "hello"的原因,看看"hello"被打印了多少次。

然而,即使前几次迭代没有产生错误,我认为正在执行的计算结果不正确,这是一个SLAM代码,所以在输出中我可以看到结果,然后才得到分割错,不应该是它应该是什么。

你能看到这个循环中有什么东西可以使用这个pragma生成这个错误吗?

2 个答案:

答案 0 :(得分:1)

首先,我认为减少(+:ptx,pty)不是你需要的。串行代码假设ptx和pty在每次下一次迭代时都会递增,因为它们的值在getInterpolatedElement31调用中使用。但是通过减少,每次迭代都会得到相同的值= ptx(pty)的初始值。

其次,共享变量 bestU bestV bestEnergy bestIdx 可能会被多个线程同时更新< / p>

bestU = ptx; bestV = pty; bestEnergy = energy; bestIdx = i;

所以,你需要在这里进行一些同步。

答案 1 :(得分:-1)

  

在输出中我可以看到结果,在我得到分段错误之前,不是它本应该是什么。

嗯,在内容方面正确运行代码时,检查一个问题是公平的。然而,让我草拟一些关于主要问题可能出现在哪里的提示,或者如何使用石器时代策略来构建根本原因......

通常的做法是使用已知解决方案的数据集,以便通过重新运行已知的测试集来提前检测错误/确认流程设计对生成结果的有效性。 / p>

  

遇到分段错误......我无法理解为什么

一般嫌疑人是:
声明/解决相关,如下所示:
idx == patternNum - 1 rotatetPattern[idx] [ {0|1} ]
idx == patternNum - 1 color[idx]
i == numStep errors[i]
? hostToFrame_affine []
? wG []

调用签名和/或实现细节,如下所示:
float getInterpolatedElement31 (...){ ... }
float fabs ( ... ){ ... }

最简单的下一步?首先观看吸烟枪的踪迹......总是......

现在最简单的步骤是在每个执行行之后添加一个DEBUG-trailing-stop行:

FLINTSTONEs_DEBUG_LOG( 0 ); // ------------------------------------------------

#pragma omp parallel for schedule(static) reduction(+:ptx,pty)
    for( int i =  0;
             i <  numSteps;
             i++
             )
    {   
        FLINTSTONEs_DEBUG_LOG( 1 ); // ----------------------------------------

        float energy = 0;

        FLINTSTONEs_DEBUG_LOG( 2 ); // ----------------------------------------

        for ( int idx =  0;
                  idx <  patternNum;
                  idx++
                  )
        {   FLINTSTONEs_DEBUG_LOG( 3 ); // ------------------------------------

            float hitColor = getInterpolatedElement31(
                                         frame->dI,
                                 (float)( ptx
                                        + rotatetPattern[idx][0]
                                          ),
                                 (float)( pty
                                        + rotatetPattern[idx][1]
                                          ),
                                        wG[0]
                                 );

            FLINTSTONEs_DEBUG_LOG( 4 ); // -----------------------------------

            if ( !std::isfinite( hitColor ) )
            {    
                  FLINTSTONEs_DEBUG_LOG( 5 ); // -----------------------------

                  energy += 1e5;

                  FLINTSTONEs_DEBUG_LOG( 6 ); // -----------------------------

                  continue;

                  FLINTSTONEs_DEBUG_LOG( 7 ); // -------------------------- ;)
            }

            float residual = hitColor
                           - (float) ( hostToFrame_affine[0]
                                     * color[idx]
                                     + hostToFrame_affine[1]
                                       );

            FLINTSTONEs_DEBUG_LOG( 8 ); // -----------------------------------

            float hw = setting_huberTH > fabs( residual )
                     ? 1
                     : setting_huberTH / fabs( residual );

            FLINTSTONEs_DEBUG_LOG( 9 ); // -----------------------------------

            energy += hw
                    * residual
                    * residual
                    * ( 2 - hw );

            FLINTSTONEs_DEBUG_LOG( 10 ); // ----------------------------------

        }

        FLINTSTONEs_DEBUG_LOG( 11 ); // --------------------------------------
        ...
        ..
        .

使用:

        void FLINTSTONEs_DEBUG_LOG( int TracePOINT )
        {    printf( "ACK: thread[%d]'s smoke-trail has reached TracePOINT( %d )\n",
                     omp_get_thread_num(),
                     TracePOINT
                     );
        }

当然,这不是火箭科学,但可能很容易向你展示下一个SegFault印刷后的烟雾痕迹,所以在这里也值得一提。

Yabba Dabba Doo,让它一步一步地坚持下去。