从openmp并行区域调用多线程MKL

piy*_*sao 3 multithreading openmp intel-mkl

我有一个具有以下结构的代码

#pragma omp parallel
{
    #omp for nowait
    {
        // first for loop
    }

    #omp for nowait 
    {
        // first for loop
    }

    #pragma barrier 

    <-- #pragma omp single/critical/atomic --> not sure 
    dgemm_(....)

    #pragma omp for
    {
        // yet another for loop  
    }

}
Run Code Online (Sandbox Code Playgroud)

对于dgemm_,我链接多线程mkl.我希望mkl使用所有可用的8个线程.这样做的最佳方法是什么?

Hri*_*iev 5

这是嵌套并行性的一种情况.它受MKL支持,但仅当您的可执行文件是使用英特尔C/C++编译器构建时才有效.这种限制的原因是MKL使用Intel的OpenMP运行时,并且不同的OMP运行时彼此不能很好地运行.

一旦整理出来,你应该通过设置使嵌套并行OMP_NESTED,以TRUE通过设置禁用MKL的检测嵌套并行MKL_DYNAMICFALSE.如果要dgemm_共享要处理的数据,则必须从single构造中调用后者.如果每个线程处理自己的私有数据,那么您不需要任何同步构造,但使用多线程MKL也不会给您带来任何好处.因此,我认为你的案子是前者.

总结一下:

#pragma omp single
dgemm_(...);
Run Code Online (Sandbox Code Playgroud)

并运行:

$ MKL_DYNAMIC=FALSE MKL_NUM_THREADS=8 OMP_NUM_THREADS=8 OMP_NESTED=TRUE ./exe
Run Code Online (Sandbox Code Playgroud)

您还可以使用适当的调用设置参数:

mkl_set_dynamic(0);
mkl_set_num_threads(8);
omp_set_nested(1);

#pragma omp parallel num_threads(8) ...
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

虽然我更愿意使用环境变量.