5

ブロック行列の乗算を実行したい (行列を複数の sxs 行列に分割し、対応するブロックを乗算する)。ヘネシーのアーキテクチャブックのサンプルコードに従って、コードを記述しました。

for(int jj=0;jj<=(n/s);jj += s){
            for(int kk=1;kk<=(n/s);kk += s){
                    for(int i=1;i<=(n/s);i++){
                            for(int j = jj; j<=((jj+s-1)>(n/s)?(n/s):(jj+s-1)); j++){
                                    temp = 0;
                                    for(int k = kk; k<=((kk+s-1)>(n/s)?(n/s):(kk+s-1)); k++){
                                            temp += b[i][k]*a[k][j];
                                    }
                                    c[j][i] += temp;
                            }
                    }
            }
    }  

ここで、nxn は元の行列のサイズです。a、b 行列は同じサイズです。a,b 行列をサイズ sxs のブロックに分割しています。私のプログラムでは、ブロック サイズを 4 に指定しました。a、b のすべての要素を 5、定数、n = 1000 にしました。ただし、結果に間違った値が表示されます。私はここで何か間違っていますか?過去2時間からこれにこだわった。可能であれば、助けてください。本の参照コードは次のようになります。

for (jj = 0; jj <= size; jj += N) {
    for (kk = 1; kk <= size; kk += N) {
        for (i = 1; i <= size; i++) {
            for (j = jj; j <= findMin(jj+N-1, size); j++) {
                temp = 0;
                for (k = kk; k <= findMin(kk+N-1, size); k++) {
                    temp += B[i][k] * A[j][k];
                }
                C[j][i] += temp;
            }
        }
     }
}  

ここで、s=N およびサイズ = n/s

4

3 に答える 3

6
for(int jj=0;jj<N;jj+= s){
        for(int kk=0;kk<N;kk+= s){
                for(int i=0;i<N;i++){
                        for(int j = jj; j<((jj+s)>N?N:(jj+s)); j++){
                                temp = 0;
                                for(int k = kk; k<((kk+s)>N?N:(kk+s)); k++){
                                        temp += a[i][k]*b[k][j];
                                }
                                c[i][j] += temp;
                        }
                }
        }
}

A×BサイズはN

于 2013-04-20T18:26:52.237 に答える
1

一見すると、開始インデックスが 0 と 1 の両方で、ループ終了テストが <= であることに驚きました。c/c++ では 0 ベースのインデックスが使用されているのに対し、fortran または matlab コードのいずれかを含む書籍では、1 ベースのインデックスが想定される場合があります。

内側の 2 つの for ループを個別に実装および/またはテストすることもできます。これらは単一ブロックの行列乗算用であるためです。

ループ テストでインライン化する代わりに、findMin 関数を個別に保持します。

于 2013-04-20T02:20:05.580 に答える