倍精度の大きな値の行列を乗算できる効率的なアルゴリズムを作成しようとしています。アルゴリズムを作成し、最初に小さな行列でテストしました。つまり、A{4096x4096}、B{4096x4096} を試した後、ループは永遠に終了します。たとえば、これらの 2 つの行列で AB を生成するには、コンピューターが完了するまでに 30 分以上かかりました。
私のコンピューターは古い前かがみではありません... 6 コアの i7 であり、デスクトップ ワークステーションとしてはそれほど悪くはないと思います。1024x1024 までのサイズの小さな行列では、比較的短時間で完了します。つまり、30 ~ 40 秒未満で、2048x2048 の場合は約 5 分です... 16384x16384 の場合は 15 分で終了せず、実行を停止しました...
私は何か間違ったことをしていますか、それともこれは予想されることですか? :)
前もって感謝します!
コードは次のとおりです。
/* calculate */
for(travx = 0; travx < m; travx++) {
for(travy = 0; travy < n; travy++) {
/* we only need to calculate it ourside of Z loop */
tIndex = (travy)+(travx*n);
for(travz = 0; travz < p; travz++)
{
if(n==1)
{bIndex = ((n-1)*travy)+travz;
aIndex = ((p)*travx)+travz;}
else
{bIndex = ((n)*travz)+travy;
aIndex = ((p)*travx)+travz;}
temp = atab_ptr[aIndex]*btab_ptr[bIndex];
outtab_ptr[tIndex] = outtab_ptr[tIndex] + temp;
}
}
}
それは本当に簡単です...そして小さな行列で素晴らしい結果をもたらします...特にp4で10秒未満でdoubleを乗算する方法がわかりません...ちょっと怪しげに聞こえます...特にO(3)を考慮に入れる場合問題の複雑さ。
更新...フィードバックに基づいてコードを微調整しました...まあ、主にそれを単純化し、小さな行列をはるかに高速に完了しました。つまり、1024x1024 は 3 秒以内に完了しますが、4096x4096 は 6 分で完了します。 . 改訂されたコードは次のとおりです。
for(travx = 0; travx < m; travx++) {
for(travy = 0; travy < n; travy++) {
for(travz = 0; travz < p; travz++)
{outtab_ptr[travy+travx*n] = outtab_ptr[travy+travx*n] + atab_ptr[travy+p*travz] * btab_ptr[travz+travx*p];}
}
}