您可以做的最接近的事情是让一个由两个线程组成的团队执行一个 OpenMP 并行区域,然后从每个线程调用 MKL。您必须在 MKL 中启用嵌套并行(通过禁用动态线程),将 MKL 线程数固定为 6,并且必须使用英特尔的编译器套件来编译您的代码。MKL 本身使用 OpenMP 进行线程化,但它是英特尔的 OpenMP 运行时。如果您碰巧使用了其他编译器,例如 GCC,它的 OpenMP 运行时可能与 Intel 的不兼容。
由于您没有指定语言,我提供了两个示例 - 一个在 Fortran 中,一个在 C/C++ 中:
Fortran:
call mkl_set_num_threads(6)
call mkl_set_dynamic(0)
!$omp parallel sections num_threads(2)
!$omp section
call dgemm(...)
!$omp end section
!$omp section
call dgemm(...)
!$omp end section
!$omp end parallel sections
C/C++:
mkl_set_num_threads(6);
mkl_set_dynamic(0);
#pragma omp parallel sections num_threads(2)
{
#pragma omp section
{
cblas_dgemm(...)
}
#pragma omp section
{
cblas_dgemm(...)
}
}
一般来说,您不能为 MKL 创建线程子集(至少考虑到我目前的理解)。每个 DGEMM 调用将使用全局指定数量的 MKL 线程。请注意,MKL 操作可能会针对 CPU 的缓存大小进行调整,并且并行执行两个矩阵乘法可能没有好处。如果您有一个带有两个六核 CPU 的 NUMA 系统,每个 CPU 都有自己的内存控制器(我怀疑是您的情况),您可能会这样,但您必须注意数据的放置位置并启用线程的绑定(固定)到核心。