OpenMP OpenBLAS嵌套并行性

时间:2019-03-09 17:53:56

标签: multithreading openmp openblas

我们正在尝试并行运行两个cblas_dgemm实例。如果线程总数为16,我们希望每个实例使用8个线程运行。当前,我们使用的是这样的结构:

#pragma omp parallel num_threads(2)
{
   if (omp_get_thread_num() == 0){
     cblas_dgemm(...);
   }else {
     cblas_dgemm(...);
   }
}

这里是问题:

在顶层,有两个OpenMP线程,每个线程在if / else块之一中处于活动状态。现在,我们希望那些调用cblas_dgemm函数的线程是并行的,并且在那些cblas_dgemm函数内部,我们希望会产生新的线程。

要设置每个cblas_dgemm内部的线程数,我们设置相应的环境变量:setenv OPENBLAS_NUM_THREADS 8 但是,它似乎不起作用。如果我们测量每个并行调用的运行时,则运行时值是相等的,但当未使用嵌套并行性且环境变量OPENBLAS_NUM_THREADS设置为1时,它们等于单个cblas_dgemm调用的运行时。

出了什么问题?怎样才能达到预期的行为? 有什么办法可以知道cblas_dgemm函数内部的线程数?

非常感谢您的时间和帮助

1 个答案:

答案 0 :(得分:0)

您尝试使用的机制称为“嵌套”,即在外部现有的并行区域中创建新的并行区域已处于活动状态。虽然大多数实现都支持嵌套,但是默认情况下它是禁用的。尝试在命令行上设置OMP_NESTED=true或在代码中的第一个OpenMP指令之前调用omp_set_nested(true)

我也将上面的代码更改为:

#pragma omp parallel num_threads(2)
{
#pragma omp sections
#pragma omp section
    {
        cblas_dgemm(...);
    }
#pragma omp section
    {
        cblas_dgemm(...);
    }
}

这样,代码还将仅使用一个线程来计算正确的事物,从而将对dgemm的两个调用序列化。在您的仅具有一个线程的示例中,代码将运行,但是错过了第二个dgemm调用。