저는 지난 2 년 동안 인터넷에서 C++을 배웠고 마침내 MPI에 대해 알아봐야 할 필요성이 생겼습니다. 나는 stackoverflow와 나머지 인터넷 (http://people.sc.fsu.edu/~jburkardt/cpp_src/mpi/mpi.html 및 https://computing.llnl.gov/tutorials/mpi/#LLNL 포함)을 수색했다. 나는 아래로 논리의 일부를 가지고 생각하지만, 나는 다음과 같은 주위에 내 머리를 포장 힘든 시간을 보내고 있습니다 : 위의MPI C++ 행렬 추가, 함수 인수 및 함수 반환
#include (stuff)
using namespace std;
vector<double> function(vector<double> &foo, const vector<double> &bar, int dim, int rows);
int main(int argc, char** argv)
{
vector<double> result;//represents a regular 1D vector
int id_proc, tot_proc, root_proc = 0;
int dim;//set to number of "columns" in A and B below
int rows;//set to number of "rows" of A and B below
vector<double> A(dim*rows), B(dim*rows);//represent matrices as 1D vectors
MPI::Init(argc,argv);
id_proc = MPI::COMM_WORLD.Get_rank();
tot_proc = MPI::COMM_WORLD.Get_size();
/*
initialize A and B here on root_proc with RNG and Bcast to everyone else
*/
//allow all processors to call function() so they can each work on a portion of A
result = function(A,B,dim,rows);
//all processors do stuff with A
//root_proc does stuff with result (doesn't matter if other processors have updated result)
MPI::Finalize();
return 0;
}
vector<double> function(vector<double> &foo, const vector<double> &bar, int dim, int rows)
{
/*
purpose of function() is two-fold:
1. update foo because all processors need the updated "matrix"
2. get the average of the "rows" of foo and return that to main (only root processor needs this)
*/
vector<double> output(dim,0);
//add matrices the way I would normally do it in serial
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < dim; j++)
{
foo[i*dim + j] += bar[i*dim + j];//perform "matrix" addition (+= ON PURPOSE)
}
}
//obtain average of rows in foo in serial
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < dim; j++)
{
output[j] += foo[i*dim + j];//sum rows of A
}
}
for (int j = 0; j < dim; j++)
{
output[j] /= rows;//divide to obtain average
}
return output;
}
코드는 개념을 설명하는 것입니다. 내 주된 관심사는 행렬 추가를 병렬 처리하는 것이지만, 내 마음을 두드리는 것은 다음과 같습니다.
1) 각 프로세서가 해당 루프의 일부에서만 작동하면 (당연히 프로세서 당 루프 매개 변수를 수정해야합니다) 어떤 명령 A의 모든 부분을 모든 프로세서가 메모리에 가지고있는 업데이트 된 단일 A로 병합하는 데 사용합니까? 내 생각 엔 각 프로세서가 A의 부분을 다른 모든 프로세서로 보내는 일종의 Alltoall을 수행해야하지만, 어떻게하면 (예를 들어) 행 3이 프로세서 3에서 작업했는지를 다른 프로세서의 행 3을 덮어 쓰게하고, 우연히 행 1이 아닙니다.
I는, 함수() 내부에 Alltoall을 사용하는 모든 프로세서() 함수에 단계 허용해야 또는 I 사용) (기능 분리 할 수 않으면 2) ...
if (id_proc == root_proc)
{
result = function(A,B,dim,rows);
}
... 및 function() 함수는 모든 병렬 처리를 처리합니다. 어리석은 것처럼 들리는 바, 하나의 프로세서 (브로드 캐스트 포함)에서 많은 작업을하고, 많은 시간을 소모하는 루프를 병렬화하려고합니다. 개념적으로 간단하게 코드를 유지하려고하므로 결과를 얻고 계속 진행할 수 있습니다.
3) 평균화 부분에서는 평행 화하려는 경우 축소 명령을 사용할 수 있습니다. 맞습니까?
또한, 옆으로 : Bcast()를 호출하여 차단하는 방법이 있습니까? 내 모든 프로세서를 동기화하는 데 사용하고 싶습니다 (라이브러리를 향상시키는 것은 옵션이 아닙니다). 그렇지 않다면 나는 Barrier()와 함께 갈 것이다. 이 질문에 대한 답변과 지난 2 년간 프로그래밍 방법을 배운 stackoverflow 커뮤니티에 감사드립니다. :)
도움 주셔서 감사합니다. 1)에 대한 응답으로, 모체가 모든 프로세서 사이에서 균등하게 나뉘어 질 것이라고 보장 할 수 없기 때문에, 수집하는 벡터의 길이가 달라집니다. MPI_Allgatherv를 사용해야한다는 것을 읽었습니다. 내가 무엇을 할 수 있는지 알아볼 게. 다시 한 번 감사드립니다! –