このページでは並列プログラミングの第一歩として, 行列の足し算を並列化します. 行列の足し算の並列化は非常に簡単です. 実際にプログラムを動かして,並列プログラムの効果を確かめましょう.
行列の足し算は行列の各要素を足し合わせたものになります.
実際に行列の足し算を行うプログラムを作成していきます. 以下にプログラムの一部を掲載します. すべてのコードは配布パッケージのapp/sample/matrixadd/matrixadd_s.cに存在します.
#include <stdio.h> #include <MClib.h> #define MATRIX_SIZE 600 int a[MATRIX_SIZE][MATRIX_SIZE]; int b[MATRIX_SIZE][MATRIX_SIZE]; int c[MATRIX_SIZE][MATRIX_SIZE]; int main() { int id_x, id_y, rank_x, rank_y; MC_init(&id_x, &id_y, &rank_x, &rank_y); if (id_x == 1 && id_y == 1) { // 行列の初期化 int i, j; for (i = 0; i < MATRIX_SIZE; i++) { for (j= 0; j < MATRIX_SIZE; j++) { a[i][j] = i * j; b[i][j] = j + i; } } // ここから計測 unsigned long long int start_clock; MC_clock(&start_clock); // 行列の足し算 for (i = 0; i < MATRIX_SIZE; i++) { for (j= 0; j < MATRIX_SIZE; j++) { c[i][j] = a[i][j] + b[i][j]; } } // 経過時間の表示 unsigned long long int clock; MC_clock(&clock); printf("cycle: %llu\n", clock - start_clock); } MC_finalize(); return 0; }
このプログラムは行列aと行列bを足し合わせ,行列cを作成します. 単純な2重ループですべての要素を足し合わせています. コンパイルして実行してみましょう.
## SimMc M-Core alpha : Many-Core and NoC Simulator v1.1 2010-07-30 ## [SimMips: Simple Computer Simulator of MIPS Version 0.5.0 2008-11-05] ## DEBUG MODE 0, LOG MODE 0 ## comp node (1,1) - (1,1) ## memory node (0,0) ## path node (0,1) - (0,1), (1,0) - (1,0) ## Multi-Core library MClib v1.0.0 2009-12-16 cycle: 3247214 ## Simulation time 2.781 [sec] ## Simulation cycle 5792399 ## Simulation 2083.115 kilo cycle / sec
1コア実行では325万サイクルかかりました.
ここからはM-Coreアーキテクチャ上で行列の足し算を並列化していく方法について, 書いていきます. 並列化の方針として,与えられた行列を部分行列に分割し計算する方法をとります.
3×3のノードを持つM-Coreで,部分行列に分けて計算する例を下の図に示します.
計算はまずNode(1,1)が各コアに計算すべき部分行列を配布します. 各コアは部分行列が届いたのを確認した後,足し算を行います. 計算終了後,各コアはNode(1,1)に計算結果を送信します.
コードは配布パッケージのapp/sample/matrixadd/matrixadd.cに存在します. また,ソースコードに解説を加えた図を こちらから表示できます.
それではコンパイルして実行してみましょう. 今回は3×3のノードで実行します.
## SimMc M-Core alpha : Many-Core and NoC Simulator v1.1 2010-07-30 ## [SimMips: Simple Computer Simulator of MIPS Version 0.5.0 2008-11-05] ## DEBUG MODE 0, LOG MODE 0 ## comp node (1,1) - (3,3) ## memory node (0,0) ## path node (0,1) - (0,3), (1,0) - (3,0) ## Multi-Core library MClib v1.0.0 2009-12-16 cycle: 1477073 ## Simulation time 11.907 [sec] ## Simulation cycle 4024070 ## Simulation 337.956 kilo cycle / sec
9コア実行では148万サイクルかかりました. 1コアと比較すると約2.2倍の高速化となります. 9コアで9倍高速化しない理由は, 初期行列の配布と計算結果の集計にかかる通信時間のためです. 通信を最適化することでさらなる高速化が可能です. また,行列和のほかにも並列化できるプログラムは多数存在します. SimMcを利用して,様々な並列プログラムに触れてみましょう.
Copyright(c) 2010, Tokyo Tech Kise Laboratory. All rights reserved.