我试图并行化一个单一的MCMC链,这个链在本质上是顺序的,因此我需要保留正在执行的迭代顺序。为此,我想通过OpenMP使用'ordered for'循环。我想知道如何在OpenMP中执行一个有序的for循环真的起作用,它真的提供了代码并行化方面的加速吗?在OpenMP中为'循环效率'排序
谢谢!
我试图并行化一个单一的MCMC链,这个链在本质上是顺序的,因此我需要保留正在执行的迭代顺序。为此,我想通过OpenMP使用'ordered for'循环。我想知道如何在OpenMP中执行一个有序的for循环真的起作用,它真的提供了代码并行化方面的加速吗?在OpenMP中为'循环效率'排序
谢谢!
只要你具有只是一个单一的马尔可夫链,并行它是最简单的方法使用'尴尬'并行:运行一堆独立链并在完成所有工作时收集结果[或者偶尔收集结果。]
这样您就不会发生任何通信开销。
这里的主要警告是,你需要确保不同的链获得不同的随机数发生器种子。
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 ordered指令只能在动态透视图中列出。
规范建议,虽然写作,我们必须提到有序的关键字。但是,循环中的哪个位置是有序的块是您的选择。
我的猜想是即使我们提到有序关键字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);
}
}
}
我对如何从不同的连锁店收集结果感到困惑。你能帮我解决吗?如同,独立小型连锁企业的结果应该如何结合才能获得最终结果? – user1105630
@ user1105630我已经更新了答案。我通常做的,我有shell脚本来运行链,还有一个单独的程序,它读入所有链的分箱统计信息并生成最终结果。 –
非常感谢您的帮助。如果不是x1,y1,z1,x2,y2 ..,我使用x1,x2,x3,..,y1,y2,y3 ...,z1,z2,z3 ..会是有效的吗? 或者合并应该在每一步完成? – user1105630