gpt4 book ai didi

multithreading - 从 openmp 并行区域调用多线程 MKL

转载 作者:行者123 更新时间:2023-12-04 08:27:37 25 4
gpt4 key购买 nike

我有一个具有以下结构的代码

#pragma omp parallel
{
#omp for nowait
{
// first for loop
}

#omp for nowait
{
// first for loop
}

#pragma barrier

<-- #pragma omp single/critical/atomic --> not sure
dgemm_(....)

#pragma omp for
{
// yet another for loop
}

}

对于 dgemm_,我与多线程 mkl 链接。我希望 mkl 使用所有可用的 8 个线程。最好的方法是什么?

最佳答案

虽然这篇文章有点过时,但我仍然想为此提供一些有用的见解。

从功能的角度来看,上述答案是正确的,但从性能的角度来看不会给出最佳结果。原因是大多数 OpenMP 实现在线程到达障碍或没有工作要做时不会关闭线程。相反,线程将进入自旋等待循环并在等待时继续消耗处理器周期。

在示例中:

#pragma omp parallel
{
#omp for nowait
for(...) {} // first loop

#omp for
for(...) {} // second loop

#pragma omp single
dgemm_(....)

#pragma omp for
for(...) {} // third loop
}

将会发生的是,即使 dgemm调用在 MKL 内部创建了额外的线程,外层线程仍将积极等待 single 的结束构造,因此 dgemm将以降低的性能运行。

这个问题基本上有两种解决方案:

1)列表项使用上面的代码,除了建议的环境变量外,还禁用主动等待:
$ MKL_DYNAMIC=FALSE MKL_NUM_THREADS=8 OMP_NUM_THREADS=8 OMP_NESTED=TRUE OMP_WAIT_MODE=passive ./exe

2)修改代码分割并行区域:
#pragma omp parallel
{
#omp for nowait
for(...) {} // first loop

#omp for nowait
for(...) {} // second loop
}

dgemm_(...);

#pragma omp parallel
#pragma omp for nowait
for(...) {} // third loop
}

对于解决方案 1,线程立即进入休眠模式并且不消耗周期。缺点是线程必须从这种更深的 sleep 状态中唤醒,与自旋等待相比,这会增加延迟。

对于解决方案 2,线程保持在其自旋等待循环中,并且很可能在 dgemm 时主动等待。 call 进入其并行区域。额外的连接和 fork 也会引入一些开销,但它可能比使用 single 的初始解决方案的超额订阅要好。构造或解决方案 1。

什么是最佳解决方案将取决于 dgemm 中正在完成的工作量。与 fork/join 的同步开销相比,同步开销主要由线程数和内部实现决定。

关于multithreading - 从 openmp 并行区域调用多线程 MKL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20715475/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com