2014-08-05 1 views
0

모든 프로세서에서 각 부분이 다른 프로세서로 전송되는 하나의 dimension_array가 있습니다.
아래 모양이 있다고 가정하십시오.데이터 배열에 대한 MPI Derived Datatype 생성

double a [n];

경우 N = 1,200

the size of array is 1200*sizeof(d) 

예컨대 나는 다음 단계에서

first 50 stays on rank 
next 100 goes to mod(rank+1,nproc) 
next 70 goes to mod(rank+2,nproc) 
next 80 goes to mod(rank+3,nproc) 

next 50*2 stays on rank 
next 100*2 goes to mod(rank+1,nproc) 
next 70*2 goes to mod(rank+2,nproc) 
next 80*2 goes to mod(rank+3,nproc) 

next 50 stays on rank 
next 100 goes to mod(rank+1,nproc) 
next 70 goes to mod(rank+2,nproc) 
next 80 goes to mod(rank+3,nproc) 

이 수 등
first 150 stays on rank 
next 100 goes to mod(rank+1,nproc) 
next 100 goes to mod(rank+2,nproc) 
next 150 goes to mod(rank+3,nproc) 

next 150*2 stays on rank 
next 100*2 goes to mod(rank+1,nproc) 
next 100*2 goes to mod(rank+2,nproc) 
next 150*2 goes to mod(rank+3,nproc) 

next 150 stays on rank 
next 100 goes to mod(rank+1,nproc) 
next 100 goes to mod(rank+2,nproc) 
next 150 goes to mod(rank+3,nproc) 

2000

다를 수 있습니다, 4 개 프로세서
처음 50 개 요소를 소유하는 동일한 프로세서에 머물고됩니다에 실행하고

이 데이터를 보내는 가장 좋은 방법은 무엇입니까?. 내가 현재 사용하고있는 방식 인 recv를 보내는 블로킹을 사용한다면, 나는 임시 배열 복사를 생성하여 + 1의 순위를 매긴 다음 모든 데이터를 복사한다.

newtype을 순위 부여 할 수있는 파생 데이터 형식을 만드는 방법이 있습니까? 먼저

[50 offset][100 d][200 offset][200d][350 offset][100d] 

next 100 goes to mod(rank+1,nproc) 
... 
next 100*2 goes to mod(rank+1,nproc) 
... 
next 100 goes to mod(rank+1,nproc) 

에 다음 단계

[150 offset][100 d][450 offset][200d][650 offset][100d] 

개조 간다 데이터 유형 (순위 + 1에서 nproc) 유래의 데이터 유형을 만드는 방법 어떤 제안이 있는가 ?

각 랭크에 대해 다른 데이터 유형을 만들 수 없습니다 (랭크 +1, 랭크 + 2에 대해 다른 하나). 1024 개 이상의 프로세서가있는 경우 1024 데이터 유형을 만들어야합니다. 각 반복과 끝 부분에서 그들을 파괴

답변

0

(? 내 이전의 경험이 인덱스 데이터 유형 또는 구조체를 사용하여 다양한 데이터 유형을 작성하고 각 반복에서 그들을 해방에서하는 비싼 사람이 이것에 대해 더 알고있다) 당신은 쓰기 :

블로킹 보내기를 사용하는 경우 (현재는 내가 인 방법입니다) 임시 배열 복사를 작성하면에 필요한 모든 데이터가 복사됩니다1 등급으로 이동 한 다음 보내십시오.

반드시 그렇게 할 필요는 없습니다. 단순히 각 블록을 별도의 메시지로 보낼 수 있습니다. 성능이 문제가되면 비 차단 방식으로 보내고 마지막으로 보낸 후에 차단하십시오.

즉, 프로세스 당 하나의 메시지 만 보내려면 인덱싱 된 데이터 유형이 필요합니다.앞서 당신은 (경고로 데이터 형식을 정의하는 것

[50 offset][100 d][200 offset][200d][350 offset][100d] 

, 검증되지 않은 코드 :

귀하의 예제의 경우를 들어 : 게시 당시 this site 짧은 버전을 좋은 설명이 있지만 여기에) : 당신이 이 수신 측에 유사한 데이터 유형을 정의 할 필요가 없습니다

double a[1000]; 
MPI_Datatype newType; 
int numBlocks = 3;  // 3 blocks of data 
int displacements[3]; // at what position does each block start 
int blockLengths[3];  // how many elements does each block contain 
displacements[0] = 50; // 50 offset 
blockLengths[0] = 100; // 100 d 
displacements[1] = 200; // 200 offset 
blockLengths[1] = 200; // 200 d 
displacements[2] = 350; // 350 offset 
blockLengths[2] = 100; // 100 d 

MPI_Type_Indexed(3, blockLengths, displacements, MPI_DOUBLE, &newType); 
MPI_Type_commit(&newType); 
MPI_Send(a, 1, newType, ...); 

참고 : 수신 프로세스는 단순히 MPI_DOUBLE의 배열로이 메시지를받을 수 있습니다 제공의 수신 버퍼가 충분히 크다.

또한 데이터 형식의 레이아웃은 각 계급과 각 반복 단계 다르기 때문에, 당신은 를 정의해야하고 비슷한 데이터 타입마다 커밋 있습니다. 이전 유형은 MPI_Type_free()으로 해제해야합니다.

+0

답변 주셔서 감사합니다.하지만 이것은 정확히 문제입니다. 각 계급에 대해 다른 데이터 유형을 만들 수 없습니다 (계급 +1, 계급 + 2 ...) 프로세서, 각 반복마다 1024 데이터 형식을 만들고 끝에 그들을 파괴해야합니다, 그것은 비 블로킹을 사용하는 전체 아이디어를 망칠 것입니다뿐만 아니라 시간이 소모되지 않습니다 및 차단 sendrecv 내 이전 버전의 용어로 더 나은 것입니다 의 성능. 나는 옳은가? 나는 성을 잃어 버렸다. – ziv

+0

서로 다른 메모리 레이아웃은 다른 데이터 유형을 의미하므로 사용자가 할 수있는 일은 없습니다. 그러나 데이터 유형을 정의, 커밋 및 해제하는 비용은 실제로 메시지를 보내는 비용과 비교할 때 중요하지 않다는 것을 알게 될 것입니다. 또한, nonblocking sends를 사용할 수 있습니다 :'MPI_Type_free'는 이미 보류중인 메시지에 영향을 미치지 않으므로 데이터 타입을 자유롭게 정의/전송하고 보내고 즉시 해제 할 수 있습니다. 그것이 당신이 좋아하지 않는다면 남은 유일한 옵션은 제 첫 제안입니다. 즉, 각 프로세스에 여러 개의 메시지를 보내는 것입니다. 각각의 간단한 두 배의 배열을 사용하십시오. – suszterpatt

관련 문제