我尝试并行化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生成这个错误吗?
答案 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,让它一步一步地坚持下去。