次元が 5000x1024 の 2 つの行列を乗算する際に問題が発生しています。従来の方法でループを介して実行しようとしましたが、永遠にかかります。実装および最適化された行列演算を備えた優れたライブラリ、または 3 つのループなしでそれを実行するアルゴリズムはありますか?
2 に答える
OpenCL の使用を検討しましたか? Cloo (C# OpenCL ライブラリ) ディストリビューションの例の 1 つは、大規模な 2D 行列の乗算です。
CUDA とは異なり、OpenCL カーネルは GPU (利用可能でサポートされている場合) または CPU で実行されます。GPU では、本当に、本当に、本当に劇的な速度の向上が見られます。つまり、カーネルの効率性と GPU のコア数に応じて、10 倍から 100 倍のオーダーで、非常に劇的です。(Fermi ベースの NVidia カードは 384 から 512 の間で、新しい 600 は 1500 のようなものです。)
その方法に興味がない場合 - このような数値集約的で簡単に並列化可能な操作を行う人は GPU を使用する必要があります - 少なくとも C# の組み込みの並列化を使用していることを確認してください。
Parallel.For(
0
,5000
, (i) => {
for(var j=0;j<1024;j++)
{
result[i,j] = .....
}
);
また、GPU.NET と Brahma もチェックしてください。Brahma を使用すると、LINQ を使用して C# で OpenCL カーネルを構築できます。間違いなく学習曲線を下げます。
実行時間が約 1 時間のStrassen アルゴリズムを見てください。O(n 3 )の代わりに O (n 2.8 )を行列を乗算する単純な方法で。1 つの問題は、常に安定しているわけではありませんが、非常に高い次元では問題なく機能することです。さらに、それは非常に複雑なので、設計を再考し、マトリックスのサイズを小さくするか、問題をより小さな部分に分割することをお勧めします。
ただし、特別なプロパティのない行列の乗算 (前述のAidanなど) を最適化することはほとんど不可能であることに注意してください。ここに例を示します。Coppersmith -Winograd アルゴリズムは O(n 2.3737 ) を取り、行列の乗算に最適なアルゴリズムの 1 つです! ここでの最良のオプションは、OpenCL と GPU ( Davidが言及) を使用するか、パッケージで Python のような他の最適化されたプログラミング言語を調べることですnumpy
。
どちらにしても頑張ってください!