Parallel processing 具有for循环并行缩减功能的OpenMP

Parallel processing 具有for循环并行缩减功能的OpenMP,parallel-processing,reduction,openmp,Parallel Processing,Reduction,Openmp,我有一个for循环来迭代大量的点(大约20000个),对于每个点,它会检查点是否在某个圆柱体内(该圆柱体对于每个点都是相同的)。 此外,我想从点集中得到最高的Y坐标。 因为我需要做很多计算,而且速度很慢,所以我想用OpenMP来并行化循环。目前我有(有所减少): #pragma omp parallel用于默认(共享)私有(reducedCloudSize、reducedCloud、cylinderBottom、cylinderTop)缩减(+:ptsInside、ptsinSideLarge)

我有一个for循环来迭代大量的点(大约20000个),对于每个点,它会检查点是否在某个圆柱体内(该圆柱体对于每个点都是相同的)。 此外,我想从点集中得到最高的Y坐标。 因为我需要做很多计算,而且速度很慢,所以我想用OpenMP来并行化循环。目前我有(有所减少):

#pragma omp parallel用于默认(共享)私有(reducedCloudSize、reducedCloud、cylinderBottom、cylinderTop)缩减(+:ptsInside、ptsinSideLarge)
对于(int i=0;itestPt.y?highestYCoord:testPt.y;
如果(气缸测试头(气缸底部、气缸顶部、气缸高度*气缸高度、气缸半径*气缸半径、测试点)!=-1){
ptsInside++;
}
}
其中,CylTest_CapsFirst将检查该点是否位于气缸内部。 但是,此代码不起作用。如果我不考虑缩减(+:ptsInside,ptsInside更大)部分,它实际上可以工作,但比非并行版本慢得多。如果我包含了reduce子句,那么程序似乎永远不会进入for循环

我做错了什么


谢谢

假设您的函数
CylTest\u CapsFirst
不写入任何内容(仅读取),则需要共享的变量只有
highestYCoord
ptsInside
。唯一需要私有的变量是
i
。您不需要明确地声明这些。 但您确实需要确保没有线程同时写入共享变量。为了有效地做到这一点,您应该制作您在并行循环中编写的
highestYCoord
ptsInside
的私有版本。然后,您可以将私有版本与关键部分中的共享版本合并。只要
reducedCloudSize>>线程数
,这是有效的

#pragma omp parallel
{
    double highestYCoord_private = highestYCoord;
    int ptsInside_private = 0;
    #pragma omp for
    for (int i = 0; i < reducedCloudSize; i++){
        highestYCoord_private = highestYCoord_private > testPt.y ? highestYCoord_private : testPt.y;
        if (CylTest_CapsFirst(cylinderBottom,cylinderTop,cylinderHeight*cylinderHeight,cylinderRadius*cylinderRadius,testPt) != -1) {
                ptsInside_private++;
        }
    }
    #pragma omp critical 
    {
        highestYCoord = highestYCoord_private > highestYCoord : highestYcoord_private ? highestYCoord
        ptsInside += ptsInside_private;
    }
}
#pragma omp并行
{
双高门=最高门;
int ptsInside_private=0;
#pragma omp for
对于(int i=0;itestPt.y?highestYCoord\u private:testPt.y;
如果(气缸测试头(气缸底部、气缸顶部、气缸高度*气缸高度、气缸半径*气缸半径、测试点)!=-1){
ptsInside_private++;
}
}
#pragma-omp-critical
{
highestYCoord=highestYCoord\u private>highestYCoord:highestYCoord\u private?highestYCoord
ptsInside+=ptsInside_private;
}
}

@您有一个写入
highestYCoord
的竞态条件。用临界值或原子值修复它。您可能还想重新考虑您想要共享和私有的变量。您只向循环中的
highestYCoord
ptsInside
写入。这些需要分享。其他人(除了我)不重要。只有我需要是私人的(这应该是通过建设)。这假设
CylTest\u CapsFirst
只读取变量,不写入任何内容。@Zboson海报上还可以使用
reduce(max:highestYCoord)
来避免使用关键或原子代码,从而生成更干净、可能更快的代码。@pburka,这取决于OP的OpenMP版本。此外,我同意它会更干净,但我怀疑它会更快。我没有看到任何证据。非常感谢,这就是我一直在寻找的!
#pragma omp parallel
{
    double highestYCoord_private = highestYCoord;
    int ptsInside_private = 0;
    #pragma omp for
    for (int i = 0; i < reducedCloudSize; i++){
        highestYCoord_private = highestYCoord_private > testPt.y ? highestYCoord_private : testPt.y;
        if (CylTest_CapsFirst(cylinderBottom,cylinderTop,cylinderHeight*cylinderHeight,cylinderRadius*cylinderRadius,testPt) != -1) {
                ptsInside_private++;
        }
    }
    #pragma omp critical 
    {
        highestYCoord = highestYCoord_private > highestYCoord : highestYcoord_private ? highestYCoord
        ptsInside += ptsInside_private;
    }
}