For循环(C ++)中的OpenMP并行节-开销

时间:2018-08-08 00:04:01

标签: c++ multithreading openmp sections

我一直在进行量子模拟。每次计算势函数时,迭代求解器的一个步骤,然后执行一系列测量。这三个过程很容易并行化,并且我已经确保它们不会相互干扰。另外,有些事情相当简单,但不应并行进行。设置概述如下所示。

omp_set_num_threads(3);
#pragma omp parallel
{
    while (notDone) {
        #pragma omp sections
        {
            #pragma omp section
            {
                createPotential();
            }
            #pragma omp section
            {
                iterateWaveFunction();
            }
            #pragma omp section
            {
                takeMeasurements();
            }
        }
        #pragma omp single
        {
            doSimpleThings();
        }
    }
}

代码工作正常!我看到速度提高了,这主要与TDSE求解器一起运行的测量有关(速度提高了约30%)。但是,该程序从使用大约10%的CPU(大约一个线程)变为35%(大约三个线程)。如果潜在函数,TDSE迭代器和测量花费了同样长的时间,但它们却没有花费那么长的时间,这将是有意义的。基于速度的提高,我预计CPU使用率会达到15%左右。

我感觉这与在while循环中运行这三个线程的开销有关。更换

#pragma omp sections

使用

#pragma omp parallel sections

(并在循环之前省略两行)没有任何改变。有没有更有效的方法来运行此设置?我不确定线程​​是否在不断地被重新创建,或者在等待其他线程完成时线程是否占用了整个内核。如果我将线程数从3增加到其他任何数目,该程序将使用所需数量的资源(可能是所有CPU),并且不会获得性能提升。

1 个答案:

答案 0 :(得分:1)

我尝试了许多选项,包括使用任务代替节(具有相同的结果),切换编译器等。正如Qubit所建议的,我还尝试使用std :: async。这就是解决方案! CPU使用率从大约50%下降到30%(这与原始帖子使用的计算机不在同一台计算机上,因此数字有所不同-基本上是1.6倍CPU使用率的1.5倍性能提升)。这更接近我对这台计算机的预期。

作为参考,这是新的代码概述:

void SimulationManager::runParallel(){
    auto rV = &SimulationManager::createPotential();
    auto rS = &SimulationManager::iterateWaveFunction();
    auto rM = &SimulationManager::takeMeasurements();
    std::future<int> f1, f2, f3;
    while(notDone){
        f1 = std::async(rV, this);
        f2 = std::async(rS, this);
        f3 = std::async(rM, this);
        f1.get(); f2.get(); f3.get();
        doSimpleThings();
    }
}

使用std :: async调用这三个原始函数,然后使用将来的变量f1,f2和f3将所有内容收集回单个线程中,并避免访问问题。