在深度嵌套的for循环中减少OpenMP fork / join开销

时间:2017-02-12 16:18:09

标签: optimization openmp c++14

我正在尝试优化我的时间步长方法,它位于自适应网格上。它设置了三个类:Mesh(基类),Level(标识自适应网格的级别)和Rectangle(其中许多位于给定级别,并保存我问题的所有数据)。

推进时间步长的工作首当其冲在于Rectangle类中的函数FCTTimeStep,我已经能够在使用标准并行的多个线程上非常有效地运行(根据英特尔的VTune)最紧密的循环上的pragma:

#pragma omp parallel
{      
    #pragma omp for schedule(guided)
    for (int i=1; i<nx; i++) {
        #pragma ivdep
        for (int j=0; j<np; j++) {
            // Work
        }
    }
    #pragma omp for schedule(guided)
    for (int i=1; i<dx; i++) {
        #pragma ivdep
        for (int j=0; j<dp; j++) {
            // More Work
        }
    }
}

这让我几乎没有旋转时间并且工作正常。问题是我在整个程序运行时调用FCTTimeStep数百万次。经理类调用其Advance函数:

for (int i = 0; i < 6; i++) {  //RungeKutta Steps, must be sequential
    EMSolver->AssembleRhoAndJ(); //Single thread
    EMSolver->UpdatePotential(); //Single thread

    for (unsigned int j = 0; j < settings.q.size(); j++) {
        meshes[j]->Advance(timeStep, i); //Mesh call
    }
    settings.UpdateTime(i, timeStep); //Single thread
    EMSolver->RGKStep(i, timeStep); //Single thread
}

Mesh::Advance调用网格中的每个Level::Advance(通过for循环 - 多次,其中单线程工作),然后为每个级别调用所有矩形Rectangle::FCTTimeStep方法(再次通过for循环)。每次访问FCTTimeStep时都会调用3到10个线程for循环 - 这会导致调用clone(由于常量fork / join)导致的大量开销。使用4个线程进行的分析测试运行告诉我,25%的运行时间由此占用,12个核心超过60%。

我想尝试的是将整个程序保存在并行编译语中

#pragma omp parallel
{      
    while (t < T_stop) {
        double dt_adaptive = CalculateDt(settings.cfl);
        SM.Advance(dt_adaptive); //Call to the managers' Advance function
        #pragma omp single
        {
            //Single work
        }
    }
}

并将工作人员送到FCTTimeStep中的孤儿pragma。由于单个工作区域,这将显着增加线程旋转时间,但应该给我一个更好的通用运行时。

因此我的问题如下:有没有办法让OpenMP将工作人员单独发送到线程区域,否则以单一模式运行?否则并行区域将使每个线程调用advance方法,我不确定如何解决在多个类的嵌套for循环结构中设置正确的pragma以阻止它。

我见过这个结构:

#pragma omp parallel
#pragma omp single nowait
{
    #pragma omp task 
    // Work
    #pragma omp task
    // More Work
    #pragma omp taskwait
    // Single Work
}

即用单个,然后调用任务来控制整个区域,但这似乎不适用于for pragma。所以也许更好的问题可能是 for pragma可以设置为与 task pragma类似吗?

非常感谢任何一般性帮助或指向适当信息的链接。

0 个答案:

没有答案