我有许多进程(大约100到1000),每个进程都必须向其他进程的某些(比如大约10个)发送一些数据.(通常情况下,但如果A发送给B,B也发送给A,则不一定必要.)每个进程都知道它必须从哪个进程接收多少数据.
所以我可以使用MPI_Alltoallv,许多或大部分消息长度为零.但是,我听说出于性能原因,最好使用多个MPI_send和MPI_recv通信而不是全局MPI_Alltoallv.我不明白:如果一个系列的发送和接收呼叫,胜过一个Alltoallv通话更加高效,为什么是Alltoallv不只是为实现一个系列的发送和接收?
对我(以及其他人)来说,只使用一次全局调用会更方便.此外,我可能不得不担心没有遇到几个Send和Recv的死锁情况(可以通过一些奇偶策略或更复杂的解决方案?或者使用缓冲的send/recv?).
你是否同意MPI_Alltoallv是必须慢比,说,10 MPI_Send和MPI_Recv; 如果是,为什么和多少?
我有一个静态分配的2D数组NxN,我想发送第一i列(带i = 0 ... N-1).
我写:
int main(int argc, char **argv) {
int myrank, nprocs;
int i,j;
int matrix[N][N]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int col[N];
...
// Define type "column"
MPI_Datatype column;
MPI_Type_vector(N,1,N,MPI_INT,&column);
MPI_Type_commit(&column);
if(myrank==0){
j=0;
MPI_Send(&matrix[0][j],1,column,1,99,MPI_COMM_WORLD);
}
if(myrank==1){
// **** FIRST MODE: Don't use "column" type *****
MPI_Recv(col,N,MPI_INT,0,99,MPI_COMM_WORLD,&info);
// **** SECOND MODE: Use "column" type *****
// MPI_Recv(col,1,column_INT,0,99,MPI_COMM_WORLD,&info);
printf("\nColumn: ");
for(j=0;j<N;j++)
printf("\n %d",col[j]);
}
MPI_Type_free(&column);
MPI_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么第一个模式正确返回:
1 5 9 13
Run Code Online (Sandbox Code Playgroud)
而第二次回报错误?
1 -2 1980804601 1980804675
Run Code Online (Sandbox Code Playgroud) 我想在C++沟通STL对象,如std::map和std::list使用MPI,但我不知道如何做到这一点.
我正在使用它们的整数id排序对象列表OrderBy.我有一些具有相同id的对象,需要排序才能保持稳定.
根据微软的文档,并行化OrderBy并不稳定,但有一种实现方法可以使其稳定.但是,我找不到这样的例子.
var list = new List<pair>() { new pair("a", 1), new pair("b", 1), new pair("c", 2), new pair("d", 3), new pair("e", 4) };
var newList = list.AsParallel().WithDegreeOfParallelism(4).OrderBy<pair, int>(p => p.order);
private class pair {
private String name;
public int order;
public pair (String name, int order) {
this.name = name;
this.order = order;
}
}
Run Code Online (Sandbox Code Playgroud) 有人可以帮助我改进这些代码并给我一些提示.我试图自己创建一个OpenMP版本的Mandelbrot.我是OpenMP初学者,在这里我没有加快速度,这可能是因为#pragma omp critical我现在想不出更好的主意.
int main()
{
// picture resolution
int iX,iY;
const int ImageWidth = 1000;
const int ImageHeight = 1000;
double Cx,Cy;
const double CxMin=-2.5;
const double CxMax=1.5;
const double CyMin=-2.0;
const double CyMax=2.0;
double PixelWidth=(CxMax-CxMin)/ImageWidth; /* scaled x coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot
X scale (-2.5, 1.5) */
double PixelHeight=(CyMax-CyMin)/ImageHeight;/* scaled y coordinate of pixel (must be scaled to lie somewhere in the Mandelbrot
Y scale (-2.0, 2.0) */ …Run Code Online (Sandbox Code Playgroud) 我想并行同步我的所有vcs目录.我要去目录并运行特殊的命令行脚本来同步git或mercurial存储库.这是一个缓慢的过程,所以我想尝试使它平行.
但是我的并行线程争夺"当前目录"有困难所以我需要一些技巧在同一时间在不同的目录中工作.
当前解决方案
def syncrepos(repos):
for r in repos.split("\n"):
if r:
print("------ repository: ", r)
thrd = ThreadingSync(r)
thrd.setDaemon(True)
thrd.start()
Run Code Online (Sandbox Code Playgroud)
ThreadingSync的位置
class ThreadingSync(threading.Thread):
def __init__(self, repo):
threading.Thread.__init__(self)
self.repo = repo
def run(self):
r = self.repo.split("-t")
path = (r[0]).strip()
if len(r) < 2:
vcs = VCS.git
else:
vcs = {
'git' : VCS.git,
'git git' : VCS.git_git,
'git hg' : VCS.git_mercurial,
'git svn' : VCS.git_subversion,
'git vv' : VCS.git_veracity,
'hg hg' : VCS.hg_hg}[(r[1]).strip()]
os.chdir(path)
if vcs == VCS.git:
checkGitModifications()
gitSync()
... …Run Code Online (Sandbox Code Playgroud) python directory parallel-processing multithreading multiprocessing
假设我需要办理两个功能f: String => A,并g: A => B以每条线在一个大的文本文件来创建最终的名单B.
由于文件大,f而且g价格昂贵,我想作出处理并发.我可以使用"平行集合",并完成类似io.Source.fromFile("data.txt").getLines.toList.par.map(l => g(f(l)),但它不执行读取文件,f和g同时进行.
在这个例子中实现并发的最佳方法是什么?
我有一个python脚本,我希望大致这样做:
将一些粒子位置调用到数组中
在所有512 ^ 3个位置上运行算法以将它们分配到NxNxN矩阵
将该矩阵反馈给python
使用python中的绘图来可视化矩阵(即mayavi)
首先我必须连续编写它,但理想情况下我想并行化第2步以加速计算.什么工具/策略可能会让我开始.我知道Python和Fortran很好但不太关于如何将这两个连接到我的特定问题.目前我正在Fortran中完成所有工作,然后加载我的python程序 - 我想立刻完成所有工作.我听说过py2f,但是在我走下一个特定的兔子洞之前,我希望得到经验丰富的人的意见.谢谢
编辑:我想要平行的东西是"令人尴尬的平行",因为它只是一个N粒子循环,我想尽快通过这个循环.
我正在进行分子动力学模拟,并且我一直在努力并行实现它,虽然我成功地完全加载了我的4线程处理器,但并行计算时间大于计算时间.串行模式.
研究每个线程在哪个时间点开始并完成其循环迭代,我注意到一个模式:就好像不同的线程正在等待彼此.就在那时,我把注意力转向了程序的结构.我有一个类,其实例代表我的粒子系统,包含有关粒子的所有信息和使用此信息的一些函数.我还有一个类实例,它代表我的原子间势,包含潜在函数的参数以及一些函数(其中一个函数计算两个给定粒子之间的力).
因此在我的程序中存在两个不同类的实例,它们彼此交互:一个类的一些函数引用另一个类的实例.我试图并行实现的块看起来像这样:
void Run_simulation(Class_system &system, Class_potential &potential, some other arguments){
#pragma omp parallel for
for(…)
}
Run Code Online (Sandbox Code Playgroud)
对于(...)是实际的计算,使用从数据system中的实例Class_system类,并从一些功能potential的实例Class_potential类.
我是对的,这种结构是我烦恼的根源吗?
你能否告诉我在这种情况下需要做些什么?我必须以完全不同的方式重写我的程序吗?我应该使用一些不同的工具来并行实现我的程序吗?
我目前有一个global Lock = threading.Lock(),并进行以下呼叫:
Parallel(n_jobs=2)(delayed(serialRemove)(dir,c,b,l,f) for f in os.listdir(dir))
Run Code Online (Sandbox Code Playgroud)
使用jobLib。在serialRemove,我有
Lock.acquire()
print(f+' begin')
if h in hashes:
try:
os.remove(path)
if l: print('Removing ' + path)
removed += 1
except os.error:
print('Encountered error removing file')
else:
hashes.add(h)
print(f+' end')
Lock.release()
Run Code Online (Sandbox Code Playgroud)
通话的部分结果是:
10.txt开始
11.txt开始
20.txt开始
我不明白如果我将代码放在Lock中,怎么会有两个开始打印。有什么简单的方法可以保护代码块,所以理想情况下我得到:
10.txt开始
10.txt结束
11.txt开始
11.txt结束
20.txt开始
20.txt结束
mpi ×3
python ×3
c ×2
c++ ×2
openmp ×2
arrays ×1
c# ×1
collections ×1
concurrency ×1
directory ×1
f2py ×1
fortran ×1
linq ×1
locking ×1
mandelbrot ×1
performance ×1
plinq ×1
scala ×1
sorting ×1
stl ×1