前提・実現したいこと
【前提】
行列行列積の計算にてブロッキング処理を行い性能を確認しています。
・行列サイズは NMAX*NMAX
・ブロッキング幅は BLSIZ
・行列の要素は事前に代入済み
・正しいブロッキング幅を事前に考慮しない
【実現したいこと】
NMAXが、ブロッキング幅BLSIZで割り切れないときに正しく計算できるようにする。
発生している問題
ブロッキング処理で適切なブロック幅を指定しない時に発生する、
余分な要素を考慮したアルゴリズムが思いつきません。
例:
下記のような55の行列サイズのとき、22の範囲でブロッキングした場合
[ 0, 1, 2, 3, 4]
[ 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]
[15, 16, 17, 18, 19]
[20, 21, 22, 23, 24]
列の方向ならば、
[ 0, 1]
[ 5, 6]
[ 10, 11]
[ 15, 16]
[ 20, 21]
[ a_(6,1), a_(6,2)]
のように行列サイズをオーバーしたブロッキングをしてしまう事になります。
またこの時、事前に考慮していない a_(6,1) a_(6,2) の2つの要素が参照されてしまいます。
思いついた対処方法として
1.行列サイズを超えないブロッキングのみ計算し、余りの要素を別途で計算する。
2.計算結果に影響のでない行列の要素を追加して、ブロッキング幅で割り切れる行列サイズにし計算する。
の2点を思いついたのですが、どのように実装したらいいか検討がつきません。
該当のソースコード
C
1 2#include<stdio.h> 3#include<stdlib.h> 4#include<omp.h> 5#include <time.h> 6#include<math.h> 7 8int main(){ 9 10//中略 11 12#define MAT(i,j) (i)*NMAX+(j) 13 double* a; 14 if ((a = (double*)malloc(sizeof(double) * NMAX * NMAX)) == NULL) { 15 printf("Out of memory, exit."); 16 exit(1); 17 } 18 19//中略 20 21 for (iter = 1; iter <= itermax; iter++) { 22 time1 = omp_get_wtime(); 23 for (i = 0; i < NMAX; i += BLSIZ) { 24 for (k = 0; k < NMAX; k += BLSIZ) { 25 for (j = 0; j < NMAX; j += BLSIZ) { 26 for (ii = i; ii < i + BLSIZ; ii++) { 27 for (kk = k; kk < k + BLSIZ; kk++) { 28 for (jj = j; jj < j + BLSIZ; jj++) { 29 c[MAT(ii, jj)] += a[MAT(ii, kk)] * b[MAT(kk, jj)]; 30 } 31 } 32 } 33 } 34 } 35 } 36 time2 = omp_get_wtime(); 37 } 38 39//以降計測 40 41}
補足情報
出来れば思いついた2点両方を実装し、どちらの方式の方が高性能か検証したいです。
初質問のため、説明不足があった場合は質問してください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。