私は行列-ベクトル積の高速化を検討していますが、私が読むすべては非常に大きな行列に対してそれを行う方法についてです。私の場合、行列は小さいですが、実行しなければならない回数は非常に多いです。
これを最適化する方法はありますか?小さな行列と小さなベクトルで構成される1つの大きなベクトルから非常に大きな対角ブロック行列を作成し、大きな行列ベクトルの高速化の手法を使用する方が高速でしょうか?または、グローバルマトリックスとベクトルを設定すると、そこでメリットが失われますか?
私は行列-ベクトル積の高速化を検討していますが、私が読むすべては非常に大きな行列に対してそれを行う方法についてです。私の場合、行列は小さいですが、実行しなければならない回数は非常に多いです。
これを最適化する方法はありますか?小さな行列と小さなベクトルで構成される1つの大きなベクトルから非常に大きな対角ブロック行列を作成し、大きな行列ベクトルの高速化の手法を使用する方が高速でしょうか?または、グローバルマトリックスとベクトルを設定すると、そこでメリットが失われますか?
回答:
コードを最適化する前に、まず最適化するものがあるかどうかを確認することをお勧めします。マトリックスとベクトルの積を最適化するライブラリは、キャッシュのサイズの制限とメモリからデータをロードするためのレイテンシという2つの問題に対処することで最適化します。1つ目は、他のデータで置き換える前に使用する必要があるすべてのデータについて、現在キャッシュ内にあるデータを最大限に使用することで行われます。後者は、実際に使用する前にデータをキャッシュにプリフェッチすることで行われます。
あなたのケースでは、データの算術強度が比較的少ないです-メモリからデータをロードし、それを1回だけ使用してから、次の行列に進みます。これは、最適化する2つ目の手段のみを残します。つまり、使用する前にデータをプリフェッチします。
しかし、先に述べたように、物事を最適化する前に、すでに持っているものを把握する価値があります。1秒あたりに行列ベクトル積を何回実行しているかを調べ、メモリからプロセッサにロードするために必要なバイト数を計算します。次に、これをマシンにあるプロセッサの帯域幅と比較します。物事をより速くするためにあなたができることは何もないことに気付くかもしれません。
それは実際に問題あなたの行列はキャッシュが既に含まれているためではないかもしれませんが、呼び出しされなければならないdgemv()
か、sgemv()
あなたは上のあなたの手を得ることができる最高のBLASライブラリーから、または同等。インテルMKLにアクセスできる場合は、インテルMKLを試してみてください。また、BLISまたはATLAS、あるいは他の多くの最適化されたBLASライブラリの1つを試してみてください。