我解决了一个练习,在该练习中,我不得不动量地实施SGD(随机梯度下降)。这样做的目的是事后将其并行化。
我的建议如下:
#pragma omp for schedule(static) nowait
for (int i = 0; i < size; i++)
{
const double nablaE_w = (1.0/double(B)) * (grad[i] + lambda * param[i]);
mom_w[i] = beta * mom_w[i] - eta * nablaE_w;
param[i] = param[i] + mom_w[i];
}
我使用nowait
是因为在for
循环之后,计算完成了。
但是在解决方案中,他们使用了:
#pragma omp for schedule (dynamic, 64/sizeof(double)) nowait
在阅读了几个stackoverflow-answers之后,我仍然看不到scheduling(dynamic)
的优势以及为什么他们使用chunksize = 8
在使用schedule(dynamic)时我非常小心-实际上我从不使用它,因为我不知道如何正确地执行它。
答案 0 :(得分:1)
该解决方案可能是出于以下两个原因之一:附近存在另一个不平衡的nowait循环,可能会导致线程无序到达此循环的情况,或者他们担心在运行性能高的系统上运行干扰因核心而异。使用schedule(dynamic)
实质上要昂贵得多,目前直到运行时真正正确实现nonmonotonic
为止,因此,只要工作负载平衡即可,static
是明确的选择。在这里使用动态的唯一原因是,如果预期线程之间的不平衡来自代码中的其他地方或来自干扰工作负载。