我从OpenMP并行代码段中得到"总线错误".我在下面重新创建了一个简单版本的问题.代码实际上对函数进行了很多调用,uniform_distribution使用Boost的uniform_int_distribution绘制一个0到20000之间的整数.
这篇文章警告两个线程访问同一个对象.我猜这是eng我的情况.(不幸的是,我不知道如何编写"合适的互斥包装器",正如该帖子所暗示的那样).
我想到的一个可能的脏解决方案是eng在#pragma for循环中创建一个局部并将其作为参数传递给uniform_distribution.我不喜欢这个想法,因为在我的真实代码中,我正在调用许多函数,并且传递一个本地eng会很麻烦.另外,我担心的是,如果我在内部声明,不同的线程将生成相同的随机数序列.所以我有两个要求:如何以某种方式并行化enguniform_distribution
谢谢; 任何帮助都热烈赞赏.
#include <omp.h>
#include <boost/random/uniform_int_distribution.hpp>
boost::random::mt19937 eng;
int uniform_distribution(int rangeLow, int rangeHigh) {
boost::random::uniform_int_distribution<int> unirv(rangeLow, rangeHigh);
return unirv(eng);
}
int main()
{
# pragma omp parallel for private(eng)
for (int bb=0; bb<10000; bb++)
for (int i=0; i<20000; i++)
int a = uniform_distribution(0,20000);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我是MPI的新手.我有4个进程:进程1到3填充向量并将其发送到进程0,进程0将向量收集到一个非常长的向量中.我的代码有效(发布时间太长),但进程0的recv操作很笨拙而且非常慢.
在摘要中,代码执行以下操作:
MPI::Init();
int id = MPI::COMM_WORLD.Get_rank();
if(id>0) {
double* my_array = new double[n*m]; //n,m are int
Populate(my_array, id);
MPI::COMM_WORLD.Send(my_array,n*m,MPI::DOUBLE,0,50);
}
if(id==0) {
double* all_arrays = new double[3*n*m];
/* Slow Code Starts Here */
double startcomm = MPI::Wtime();
for (int i=1; i<=3; i++) {
MPI::COMM_WORLD.Recv(&all_arrays[(i-1)*m*n],n*m,MPI::DOUBLE,i,50);
}
double endcomm = MPI::Wtime();
//Process 0 has more operations...
}
MPI::Finalize();
Run Code Online (Sandbox Code Playgroud)
事实证明,它endcomm - startcomm占总时间的50%(0.7秒,而程序完成时间为1.5秒).
有没有更好的方法从进程1-3接收向量并将它们存储在进程0中all_arrays?
我检查了MPI :: Comm :: Gather,但我不确定如何使用它.特别是,它是否允许我指定进程1的数组是all_arrays中的第一个数组,进程2的数组是第二个数组,等等?谢谢.
编辑:我删除了"慢"循环,而是将以下内容放在"if"块之间:
MPI_Gather(my_array,n*m,MPI_DOUBLE,
&all_arrays[(id-1)*m*n],n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
Run Code Online (Sandbox Code Playgroud)
导致同样缓慢的表现.这是否与根进程在尝试下一个进程之前"等待"每个接收完成的事实有关?或者这不是思考它的正确方法吗?