我们正试图并行运行两个cblas_dgemm的实例。如果线程总数为16,我们希望每个实例都使用8个线程运行。目前,我们正在使用这样的结构:
#pragma omp parallel num_threads(2)
{
if (omp_get_thread_num() == 0){
cblas_dgemm(...);
}else {
cblas_dgemm(...);
}
}
这是问题:
在顶级,在其中一个if/else块内部有两个OpenMP线程。现在,我们希望这些线程调用CBLAS_DGEMM函数是平行的,并且在这些CBLAS_DGEMM函数内部,我们希望产生新线程。
要设置每个cblas_dgemm内部的线程数,我们设置了相应的环境变量:setEnv openblas_num_threads 8但是,它似乎行不通。如果我们测量每个并行呼叫的运行时,则运行时值等于当不使用嵌套并联时,它们等于单个CBLAS_DGEMM调用的运行时,并且环境变量openblas_num_threads设置为1。
。出了什么问题?我们如何才能拥有所需的行为?有什么办法知道CBLAS_DGEMM函数内部的线程数?
非常感谢您的时间和帮助
您要使用的机制称为"嵌套",也就是说,在外部,现有的并行区域内创建一个新的并行区域已经活跃。尽管大多数实现都支持嵌套,但默认情况下它是禁用的。尝试在命令行上设置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
调用。