使用OpenMP重叠计算和通信或I / O

时间:2018-10-01 13:36:15

标签: c++ parallel-processing openmp hpc

我正在从事一个HPC项目,正在处理磁盘中的TB数据。基本流程(如果通过在每个节点上导入数据的子集表示)。生成大量其他数据并累积结果,然后导出结果。我需要做的I / O很大,几乎要花与计算一样多的时间。我希望交错计算和通信。我真的只知道OpenMP。下面是我尝试的伪代码示例。但是,这些部分似乎正在串行运行。

是否有一种方法可以强制这些部分并行运行? 有一个更好的方法吗?

while ( There are still blocks of work available ) {

#pragma  omp parallel sections num_threads(2)
{
    #pragma omp section
    {
        //Perform collective I/O 
        // Based on parallel HDF
        BigBlock block1 = ImportFunc();
    }

    #pragma omp section
    {
        while (While there are still subset blocks to process) {
            const SubSetBlock block2 = GenerateNextSubBlock(); //includes a parallel for loop

            #pragma omp parallel for default(shared) num_threads(omp_get_max_threads()-1)
            for (int i = 0; i < numVessels; ++i) {
                ProcessAllBlock2ItemsForABlock1Item(block1[i], block2);
            }

        }

    }
} //OMP Sections
}// while

2 个答案:

答案 0 :(得分:0)

根据我对大型数据集的有限经验,我发现STXXL非常有用。如果您可以足够快地提供数据,它将在后台使用OpenMP,并将使磁盘I / O饱和。

http://stxxl.org

迈克

答案 1 :(得分:0)

如果您要嵌套,则应设置  omp_set_max_active_levels(...)(在您的情况下至少为2) omp_set_nested(true)

但是,老实说,在这种情况下,我建议您使用std::future,它非常易于使用,并且可以在单独的线程上运行您的函数(请确保将std::launch::async作为第一个参数)。在嵌套方面,它通常不如OpenMP麻烦。

通话会是这样

std::future<BigBlock> block1 = std::async(std::launch::async, ImportFunc, ...);

...是您希望传递给ImportFunc的任何参数。

一旦您需要调用block1.get()的数据,这将等待线程完成(如果尚未完成),或者仅返回线程(如果拥有)。到那时,我建议您使用一个move构造函数(如果它很大,您真的不想复制它,那么您可能已经为ImportFunc准备了一个,或者正在传递指针,但是在这种情况下,如果创建另一个delete实例,并确保将其移到BigBlock的另一个实例(即您的线程中的那个)中,请确保在将来毁灭时不要BigBlock希望继续操作)。