OpenMP OpenBLAS 嵌套并行
Posted
技术标签:
【中文标题】OpenMP OpenBLAS 嵌套并行【英文标题】:OpenMP OpenBLAS nested parallelism 【发布时间】:2019-03-09 17:53:56 【问题描述】:我们正在尝试并行运行两个 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】:您尝试使用的机制称为“嵌套”,即在外部现有并行区域中创建新的并行区域已经处于活动状态。虽然大多数实现都支持嵌套,但默认情况下它是禁用的。尝试在命令行中设置 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
调用。
【讨论】:
非常感谢迈克尔。我们正在使用 omp_set_nested(true)。我已经在每个部分中放置了用于打印 openMP 线程 ID 的打印语句。我还对每个部分进行了计时,并将其与整体计时进行了比较。我们当前的 openMP 构造似乎按预期工作。我们只是不确定 openBLAS 函数中的线程。以上是关于OpenMP OpenBLAS 嵌套并行的主要内容,如果未能解决你的问题,请参考以下文章
在 OpenMP 中并行化嵌套循环并使用更多线程执行内部循环