我们正在尝试并行运行两个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函数内部的线程数?
非常感谢您的时间和帮助
答案 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
调用。