• 検索結果がありません。

pthread_cond_broadcast(&mt)

ドキュメント内 並列処理論2 (ページ 33-48)

ct

は同期変数

: pthread_cond_t ct

など

マルチスレッディングによる並列処理

34

MT -相互排除

#include <pthread.h>

#include <stdio.h>

extern int *sum(int *);

pthread_t th1, th2;

pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER;

int gsum;

int main() {

int *ps1, *ps2;

int arg1[2]={1,5}, arg2[2] = {6,10};

pthread_create(&th1,NULL,(void*(*)(void*))sum,&arg1);

pthread_create(&th2,NULL,(void*(*)(void*))sum,&arg2);

pthread_join(th1, (void**)&ps1);

pthread_join(th2, (void**)&ps2);

printf("%d+..+%d=%d¥n", arg1[0], arg2[1], gsum);

free(ps1); free(ps2);

}

和を部分和として二つの スレッドで求めるプログラム

続く

または

pthread_mutex_init(&mt, NULL);

35

int *sum(int *arg_ptr) {

int lb = *arg_ptr;

int ub = *(arg_ptr+1);

int i, sum;

for (i=lb, sum =0; i<= ub; i++) { sum += i;}

pthread_mutex_lock(&mt);

gsum=gsum+sum;

pthread_mutex_unlock(&mt);

return 0;

}

MT -相互排除

和を部分和として二つの スレッドで求めるプログラム

36

メッセージ通信ライブラリ(の

API

仕様)

プロセス間でのデータ授受のための通信関数のライブ ラリ(百数十) [1]

バージョン

1994 May MPI 1.0

・・・

2015 June MPI 3.1 MPI 4.0

複数プロセスが協調して動作する並列実行モデル プログラム開始時に複数プロセスが一斉に実行を開 始し,一斉に終了する(

MPI-1

例)

mpirun –np 8 my_program

[1] http://www.mpi-forum.org/ MPI Forum

MPI(Message-Passing Interface)

37

メッセージは次の三つの組で指定される

通信範囲を示すプロセスグループ(コミュニケータ)

プロセスグループ中でのプロセス

ID

(ランク)

通信の識別子(タグ)

MPI(Message-Passing Interface)

38

MPI ー例題プログラム

#include “mpi.h”

int main(int argc, char **argv) { int myrank, error, buffer

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == 0) {

error = MPI_Send(&buffer, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

error = MPI_Recv(&buffer, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

MPI_Finalize();

}

プロセス間でデータを 授受するプログラム

39

MPI ー例題プログラム

#include “mpi.h”

int main(int argc, char **argv) { int myrank, error, buffer

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == 0) {

error = MPI_Send(&buffer, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

error = MPI_Recv(&buffer, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

MPI_Finalize();

}

MPI

プログラムの全体の枠組み ヘッダファイルの読み込み

MPI

ライブラリの初期化

MPI

ライブラリの終了処理

40

MPI ー例題プログラム

#include “mpi.h”

int main(int argc, char **argv) { int myrank, error, buffer

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == 0) {

error = MPI_Send(&buffer, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

error = MPI_Recv(&buffer, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

MPI_Finalize();

}

バッファの指定:先頭アドレス

,

個数

,

メッセージの送受信

送受信で指定する情報

相手と文脈の指定:ランク

,

タグ

,

コミュニケータ

41

MPI ー例題プログラム

#include “mpi.h”

int main(int argc, char **argv) { int myrank, error, buffer

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == 0) {

error = MPI_Send(&buffer, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

error = MPI_Recv(&buffer, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

MPI_Finalize();

}

バッファの指定:先頭アドレス

,

個数

,

受信状態 メッセージの送受信

送受信で指定する情報

相手と文脈の指定:ランク

,

タグ

,

コミュニケータ

受信メッセージのランクやタグ(ワイルドカード受信の際に利用)など

42

MPI ー例題プログラム

#include “mpi.h”

int main(int argc, char **argv) { int myrank, error, buffer

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == 0) {

error = MPI_Send(&buffer, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

error = MPI_Recv(&buffer, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

MPI_Finalize();

}

自プロセスのランクの取得 自分のランクが

0

の場合

プロセスの識別

プログラム中の各プロセスにラ ンクが付加されそれで区別する

自分のランクが

1

の場合

43

MPI ー双方向通信例題プログラム

双方向送受信をしたい.次のコードは動作するか?

if (myrank == 0) {

MPI_Send(&sb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

MPI_Recv(&rb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD, &status);

} else if (myrank == 1) {

MPI_Send(&sb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD);

MPI_Recv(&rb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

}

ブロッキングsend/receiveのためデッドロック!

44

MPI ー双方向通信例題プログラム

双方向送受信をしたい.次のコードは動作するか?

if (myrank == 0) {

MPI_Recv(&rb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD, &status);

MPI_Send(&sb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

} else if (myrank == 1) {

MPI_Recv(&rb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

MPI_Send(&sb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD);

}

send/receiveの順序を入れ替えてもだめ

45

MPI ー双方向通信例題プログラム

双方向送受信をしたい.次のコードは動作するか?

if (myrank == 0) {

MPI_Send(&sb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD);

MPI_Recv(&rb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD, &status);

} else if (myrank == 1) {

MPI_Recv(&rb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

MPI_Send(&sb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD);

}

双方の順序を逆にする必要

46

MPI ー双方向通信例題プログラム

ノンブロッキングのIsendとWait

if (myrank == 0) {

MPI_Isend(&sb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD, &id);

MPI_Recv(&rb, 1, MPI_INT,

1, 1234, MPI_COMM_WORLD, &rstatus);

MPI_Wait(&id, &wstatus);

} else if (myrank == 1) {

MPI_Isend(&sb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &id);

MPI_Recv(&rb, 1, MPI_INT,

0, 1234, MPI_COMM_WORLD, &status);

MPI_Wait(&id, &wstatus);

}

Isendではブロッキングせずにreceiveに移行

47

MPI ー双方向通信例題プログラム

双方向送受信を指示する関数

if (myrank == 0) {

MPI_Sendrecv(&sb, 1, MPI_INT, 1, 1234,

&rb, 1, MPI_INT, 1, 1234, MPI_COMM_WORLD, &status);

} else if (myrank == 1) {

MPI_Sendrecv(&sb, 1, MPI_INT, 0, 1234,

&rb, 1, MPI_INT, 0, 1234, MPI_COMM_WORLD, &status);

}

48

典型的な通信パターンに対応する集団通信関数

交換

ドキュメント内 並列処理論2 (ページ 33-48)

関連したドキュメント