【发布时间】:2020-09-26 12:47:14
【问题描述】:
我对混合并行编码非常陌生,所以我想知道这种概念是否可行,以及它是否会导致并行化效率不佳。
假设我需要A 例程和B 例程。 A 很难与 MPI 并行化,而 B 对于 MPI 则相对简单。由于我希望这段代码在某种程度上具有可扩展性,因此我将尽可能多地利用 MPI 并行化。
我非常粗略地了解thread 和process 的概念,我想total threads 的数字是n_threads x n_process。
program Hybrid
use MPI
use OMP_LIB
call MPI_INIT ( ierr )
* call MPI_COMM_SIZE ( MPI_COMM_WORLD, n_process, ierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, my_id, ierr )
...
* call omp_set_num_threads ( n_threads )
...
call MPI_FINALIZE ( ierr )
end program
所以在上面的例子中,在我的理解中,total threads 变成了n_threads x n_process(不过我不确定我是否正确使用了total threads 这个词)。星号(*) 只是为了方便查找n_threads 和n_process。
我的序列版代码看起来像,
program Serial
do i = 1, time_steps
call A
call B
enddo
end program
A 和 B 都需要数组的全局视图。
MPI 并行化B 例程,B_MPI,以一些MPI_ScatterV 开始将其全局信息分发到子进程,并以MPI_GatherV 结束以恢复所有全局视图,并且只有'my_id == 0 ' 进程持有这个全局视图。
虽然我希望 A 与 OpenMP 并行化,但我不想激活太多 threads,因此只需要 'my_id == 0' 进程调用 OpenMP 调用,从而使 OpenMP 线程的人们如下所示。
program
use MPI
use OMP_LIB
call MPI_INIT ( ierr )
* call MPI_COMM_SIZE ( MPI_COMM_WORLD, n_process, ierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, my_id, ierr )
...
do i = 1, time_steps
if (my_id == 0) then
* call A_OMP ! 'call omp_set_num_threads ( n_threads ) ' inside the 'A_OMP'
endif
call B_MPI ! Starts with 'MPI_ScatterV', ends with 'MPI_GatherV'
enddo
end program
因此,通过这种方式,仅在“my_id == 0”内调用 OpenMP 调用,我想让total threads 像n_process + n_threads,而不是n_process x n_threads。
老实说,如果threads 与 MPI 混合使用,我不太确定他们是如何使用的。我想确定上述图片是否可行,是否有效。
感谢您阅读此问题。
【问题讨论】:
标签: multithreading fortran mpi openmp