我正在尝试并行化一个本质上是顺序的单个 MCMC 链,因此,我需要保留正在执行的迭代的顺序。为此,我正在考虑通过 OpenMP 使用“ordered for”循环。我想知道在 OpenMP 中执行有序 for 循环是如何工作的,它真的在代码并行化方面提供了任何加速吗?
谢谢!
如果您的循环仅包含一个具有有序结构的块,则执行将是串行的,并且您不会从并行执行中获得任何加速。在下面的示例中,有一个块可以并行执行,一个块将被序列化:
void example(int b, int e, float* data)
{
#pragma omp for schedule(static) ordered
for (int i = b; i < e; ++i) {
// This block can be executed in parallel
data[i] = SomeThing(data[i]);
if (data[i] == 0.0f)
{
// This block will be serialized
#pragma omp ordered
printf("Element %d resulted in zero\n", i);
}
}
}
只要你只有一条马尔可夫链,最简单的并行化方法是使用“令人尴尬”的并行性:运行一堆独立的链并在它们全部完成后收集结果[或收集结果一次一会儿。]
这样您就不会产生任何通信开销。
这里的主要警告是,您需要确保不同的链获得不同的随机数生成器种子。
UPD:收集结果的实用性。
简而言之,您只需将所有链生成的结果混合在一起。为简单起见,假设您有三个独立的链:
x1, x2, x3,...
y1, y2, y3,...
z1, z2, z3,...
从这些中,你制作了一个链x1,y1,z1,x2,y2,z2,x3,y3,z3,...
这是一个完全有效的 MC 链,它对正确的分布进行采样。
写出所有的链历史几乎总是不切实际的。通常,每个链都会保存分箱统计信息,然后您将其混合在一起并由单独的程序进行分析。对于分箱分析,请参见 [boulder.research.yale.edu/Boulder-2010/ReadingMaterial-2010/Troyer/Article.pdf][1]
openMP 有序指令只能在动态透视图中列出。
规范表明,在编写 for 时,我们必须提及ordered 关键字。但是,您可以选择循环中的有序块。
我的猜测是,即使我们在 for 中提到了 ordered 关键字,每个线程也会并行开始工作。任何遇到有序关键字的线程只有在完成所有先前的迭代后才必须进入此块。请关注关键字所有以前的迭代必须完成。
上述推理的直觉是,如果连续执行“ordered for”根本没有任何意义。