2011-05-17 30 views
0

我项目中的一个文件有一个for循环,我尝试使用OpenMP for进行并行化。当我运行它时,我得到了一个浮点异常。我无法在单独的测试程序中重现该错误,但是,我可以使用虚拟并行区域(原始for循环具有一些详细的数组计算,因此为虚拟代码)在同一文件中重现该错误:openmp并行中的浮点异常

#pragma omp parallel for 
for(i=0; i<8; i++) 
{ 
    puts("hello world"); 
} 

我仍然有同样的错误。继承人的GDB输出:

Program received signal SIGFPE, Arithmetic exception. 
[Switching to Thread 0x7ffff4c44710 (LWP 18912)] 
0x0000000000402fd4 in allocate_2D_matrix.omp_fn.0 (.omp_data_i=0x0) at main.c:119 
119  #pragma omp parallel for 

通过试错,我通过一种添加日程的OpenMP结构解决了这个问题:

#pragma omp parallel for schedule(dynamic) 
    for(i=0; i<8; i++) 
    { 
     puts("hello world"); 
    } 

和它的工作就好了。我可以在2个不同的系统上复制整个行为(64位Linux Mint上的gcc 4.4.5和64位Opensuse上的gcc 4.5.0)。 有没有人有任何想法可能导致了它?我强烈怀疑它与我的程序有关,因为我无法单独重现错误,但我不知道要在哪里查看。当然问题解决了,但我很好奇。如果需要,我可以发布整个原始功能,我看到这种行为。

+0

如果我正确地读这篇文章,它似乎像“我”的价值导致了问题。它似乎远远超过了1024的上限。“我”是如何申报的?我的猜测是你的循环中的某些东西超出了它的界限,并且在循环迭代变量的存储器上进行。这并不能解释当你用虚拟并行区域替换它时发生的同样的问题。当您使用虚拟并行区域时报告了什么? – ejd 2011-05-17 18:49:00

+0

我在循环之前声明为int i; (不是全局变量) 我已经显示的gdb输出是虚拟循环的确切输出。 – jitihsk 2011-05-17 19:02:19

+0

gdb输出'omp_data_i = 0x7fffffffe730'明确表明我的位置出了问题 – jitihsk 2011-05-17 19:07:06

回答

1

最有可能放在线程安全。把它放在关键部分,看看会发生什么。

+0

同样的错误。它使用puts示例失败,但也失败了在循环内部有数组计算的原始代码。 – jitihsk 2011-05-17 17:29:21

+0

@hor是'我'共享还是私人? – Anycorn 2011-05-17 20:48:21

+0

我是默认共享的。我也尝试在openmp结构中明确地共享/私有,但我仍然看到错误。 – jitihsk 2011-05-17 21:05:00

1

我有同样的问题,似乎使用无符号整数作为循环迭代变量时发生的,这里是有问题和修复的例子:

/* the following code was generating a FPE: */ 

unsigned int m = A->m ; 
unsigned int i,ij ; 
NLCoeff* c = NULL ; 
NLRowColumn* Ri = NULL; 

#pragma omp parallel for private(i,ij,c,Ri) 
for(i=0; i<m; i++) { 
    Ri = &(A->row[i]) ;  
    y[i] = 0 ; 
    for(ij=0; ij<Ri->size; ij++) { 
     c = &(Ri->coeff[ij]) ; 
     y[i] += c->value * x[c->index] ; 
    } 
} 

/* and this one does not: */ 

int m = (int)(A->m) ; 
int i,ij ; 
NLCoeff* c = NULL ; 
NLRowColumn* Ri = NULL; 

#pragma omp parallel for private(i,ij,c,Ri) 
for(i=0; i<m; i++) { 
    Ri = &(A->row[i]) ;  
    y[i] = 0 ; 
    for(ij=0; ij<(int)(Ri->size); ij++) { 
     c = &(Ri->coeff[ij]) ; 
     y[i] += c->value * x[c->index] ; 
    } 
}