【发布时间】:2021-12-15 17:32:02
【问题描述】:
我的任务是使用 MPI 加速程序。 假设我在输入上有一个大的二维数组(1000x1000 或更大)。我有一个工作的顺序程序,可以将二维数组分成块(例如 10x10)并计算每个卡盘的两倍结果。 (所以我们有一个函数,它的参数是 10x10 的二维数组,结果是一个双精度数)。
我的第一个加快速度的想法:
- 创建大小为 N*N 的一维数组(例如 10x10 = 100)并将数组发送到另一个进程
double* buffer = new double[dataPortionSize];
//copy some data to buffer
MPI_Send(buffer, dataPortionSize, MPI_DOUBLE, currentProcess, 1, MPI_COMM_WORLD);
- 在另一个进程中接收,计算结果,发回结果
double* buf = new double[dataPortionSize];
MPI_Recv(buf, dataPortionSize, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, status);
double result = function->calc(buf);
MPI_Send(&result, 1, MPI_DOUBLE, 0, 3, MPI_COMM_WORLD);
这个程序比顺序版本慢得多。看起来 MPI 需要很长时间才能将数组传递给另一个进程。
我的第二个想法:
- 将整个二维输入数组传递给所有进程
// data is protected field in base class, it is injected during runtime
MPI_Send(&(data[0][0]), dataSize * dataSize, MPI_DOUBLE, currentProcess, 1, MPI_COMM_WORLD);
- 并像这样接收数据
double **arrayAlloc( int size ) {
double **result; result = new double [ size ];
for ( int i = 0; i < size; i++ )
result[ i ] = new double[ size ];
return result;
}
double **data = arrayAlloc(dataSize);
MPI_Recv(&data[0][0], dataSize * dataSize, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, status);
这些崩溃是非常随机的。程序成功结束发生了2次
我的第三个想法:
将内存地址传递给所有进程,但我发现了这个:
MPI processes cannot read each others' memory, and virtual addressing makes one process' pointer completely meaningless to another.
有人知道如何加快速度吗?我知道提高速度的关键是以有效的方式将数组/数组传递给进程,但我不知道如何做到这一点。
【问题讨论】:
-
关于崩溃,
data是什么?如何声明/定义和初始化? -
接收时我正在使用函数分配内存:``` double *arrayAlloc( int size ) { double **result;结果 = 新的双倍 [大小]; for ( int i = 0; i data,我将其注入,您可以假设
data定义明确。我忘了补充。这些崩溃是非常随机的。程序成功结束发生了 2 次。 -
请edit您的问题包含代码。
-
问题是你实际上没有一个“2D”数组,你只有一个指针数组。数据不是连续的,因为它是一个适当的“2D”数组。
-
1.不,
double**不是二维数组。 2. 在“输入”上创建一个大数组是违反 MPI 精神的。它创造了记忆和时间的瓶颈。对于一个好的 MPI 程序,您将首先并行创建矩阵。 3. 当然,您的并行程序更慢:您已将网络操作引入到顺序代码中。只有摊销引入的开销才会更快。