OpenMP给出(核心转储)

时间:2015-10-05 10:28:00

标签: c openmp

我有循环,我想与OpenMP并行化。当我用segmentation fault(core dumped)编译时,我没有错误。但是当我执行它时,我得到#pragma。问题肯定来自OpenMP命令,因为当我删除ix = (i-1)%ILIGNE+1; iy = (i-1)/ILIGNE+1; k = 1; # pragma omp parallel for private(j,jx,jy,r,R,voisin) shared(NTOT,k,i,ix,iy) num_threads(2) schedule(auto) for(j = 1;j <= NTOT;j++){ if(j != i){ jx = (j-1)%ILIGNE+1; jy = (j-1)/ICOLONE+1; r[k][0] = (jx-ix)*a; r[k][1] = (jy-iy)*a; R[k] = sqrt(pow(r[k][0],2.0)+pow(r[k][1],2.0)); voisin[k] = j; k++; } } ...

时程序可以正常工作

这是并行循环:

SceneKit

我尝试将堆栈大小更改为无限制,但它无法解决问题。请告诉我它是关于内存泄漏还是竞争条件或其他什么?谢谢你的帮助

2 个答案:

答案 0 :(得分:1)

作为旁注,在将数组设为私有时要小心。

如果您将其分配为静态数组 例如 PhotoViewModel.Value或类似的东西,那就没关系,每个帖子都有自己的个人副本:)。

但是如果你int R[5] e.g:

malloc 然后它将充当共享数组,无论您是将其定义为私有(这可能会导致未定义的行为,段错误,数组中的乱码等)。

答案 1 :(得分:0)

我不确定您的代码是做什么的,但我非常确定OpenMP版本是错误的。实际上,您在j循环上进行了并行化,但算法的核心围绕kj松散地派生自ij(此处未提供)顺便说一句)。

因此,当您在OpenMP线程中分发j索引时,它们都从k的不同值开始,但都来自共享的k的相同值。从那时起,k相当随机递增,使用r访问各种数组很可能会产生分段错误。

此外,如果希望并行化产生任何影响,则不应将数组Rvoisinprivate声明为for(j = 1;j <= NTOT;j++)

最后,像for(j = 0;j < NTOT;j++)这样的C循环对于我来说对于逐个访问看起来完全可疑......难道不应该是k吗? (刚才提到这一点,因为k的初始值也是1 ...)

最重要的是,您可能最好使用jk = j<i ? j : j-1的值定义ix = (i-1)%ILIGNE+1; iy = (i-1)/ILIGNE+1; # pragma omp parallel for private(j,jx,jy,k) num_threads(2) schedule(auto) for(j = 1;j <= NTOT;j++){ if(j != i){ k = j<i ? j : j-1; jx = (j-1)%ILIGNE+1; jy = (j-1)/ICOLONE+1; r[k][0] = (jx-ix)*a; r[k][1] = (jy-iy)*a; R[k] = sqrt(pow(r[k][0],2.0)+pow(r[k][1],2.0)); voisin[k] = j; } } ,而不是尝试在代码中增加它。 假设所有其余的都是正确的,这可能是一个有效的版本:

var result = from db in dt.AsEnumerable()
             let temp = GtiplerList.Where(x => x.GtipNo.EndsWith("00")) // i assume GtipNo is a string already so no need to ToString() it
             join tescil in temp on db.Field<string>("Kod") equals tescil.GtipNo.Substring(0,6) // substring to get first 6 characters
             select db.Field<string>("AdiTR");

仍然要小心C索引从0到大小-1,而不是从1到大小......