我正在从事一个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
答案 0 :(得分:0)
答案 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
希望继续操作)。