多数のベクトルと行列の計算を含むコードを C または C++ に移行したいと考えています。その目的は、コードを可能な限り高速化することです。
C コードのループを使用した線形代数の計算はfor
、LAPACK/BLAS を使用した計算と同じくらい高速ですか?または、これらのライブラリを使用することで独自の速度向上が見られますか?
言い換えれば、単純な C コード (for
ループなどを使用) は、LAPACK/BLAS を利用するコードと同じくらい高速に線形代数計算を実行できますか?
多数のベクトルと行列の計算を含むコードを C または C++ に移行したいと考えています。その目的は、コードを可能な限り高速化することです。
C コードのループを使用した線形代数の計算はfor
、LAPACK/BLAS を使用した計算と同じくらい高速ですか?または、これらのライブラリを使用することで独自の速度向上が見られますか?
言い換えれば、単純な C コード (for
ループなどを使用) は、LAPACK/BLAS を利用するコードと同じくらい高速に線形代数計算を実行できますか?
ベンダー提供の LAPACK / BLAS ライブラリ (Intel の IPP/MKL について言及されていますが、AMD の ACML もあり、IBM/Power や Oracle/SPARC などの他の CPU ベンダーも同等のものを提供しています) は、多くの場合、特定の CPU 機能に対して高度に最適化されています。大規模なデータセットでのパフォーマンスを大幅に向上させます。
ただし、多くの場合、操作する非常に特定の小さなデータ (たとえば、4x4 行列または 4D 内積、つまり 3D ジオメトリ処理で使用される操作) があり、そのようなものについては、初期テストのために BLAS/LAPACK は過剰です。データセットのプロパティに応じて、どのコードパスを選択するかは、これらのサブルーチンによって行われます。そのような状況では、単純な C/C++ ソースコード (おそらく SSE2...4 組み込み関数および/またはコンパイラー生成のベクトル化を使用) が BLAS/LAPACK に勝る可能性があります。
そのため、たとえば Intel には 2 つのライブラリがあります。大規模な線形代数データセット用の MKL と、小さな(グラフィックス ベクトル) データセット用の IPP です。
そういう意味では、
また、「単純な for ループ」について: コンパイラーにベクトル化する機会を与えてください。つまり、次のようなものです。
for (i = 0; i < DIM_OF_MY_VECTOR; i += 4) {
vecmul[i] = src1[i] * src2[i];
vecmul[i+1] = src1[i+1] * src2[i+1];
vecmul[i+2] = src1[i+2] * src2[i+2];
vecmul[i+3] = src1[i+3] * src2[i+3];
}
for (i = 0; i < DIM_OF_MY_VECTOR; i += 4)
dotprod += vecmul[i] + vecmul[i+1] + vecmul[i+2] + vecmul[i+3];
プレーンよりもベクトル化コンパイラへのより良いフィードかもしれません
for (i = 0; i < DIM_OF_MY_VECTOR; i++) dotprod += src1[i]*src2[i];
表現。ある意味では、for ループを使用した計算が意味することは、大きな影響を与えます。
ただし、ベクトルの次元が十分に大きい場合は、BLAS バージョン、
dotprod = CBLAS.ddot(DIM_OF_MY_VECTOR, src1, 1, src2, 1);
よりクリーンなコードになり、おそらくより高速になります。
参照側では、これらは興味深いかもしれません:
おそらくそうではありません。lapack / BLASルーチンが最適化され、数値的に安定していることを確認するために、人々はかなりの作業を行っています。多くの場合、コードはやや複雑な側面にありますが、通常はそのようになっているのには理由があります。
目的のターゲットによっては、インテルマス・カーネル・ライブラリーを確認することをお勧めします。少なくとも、Intelプロセッサをターゲットにしている場合は、おそらくこれが最も高速です。
数値解析は難しい。少なくとも、浮動小数点演算の限界を十分に認識し、速度と数値の安定性のバランスを取るように演算を順序付ける方法を知っている必要があります。これは自明ではありません。
実際に必要な速度と安定性のバランスについて、実際に手がかりを得る必要があります。より一般的なソフトウェア開発では、時期尚早の最適化が諸悪の根源です。数値解析では、ゲームの名前です。最初にバランスを正しく取らなければ、多かれ少なかれすべてを書き直す必要があります。
線形代数の証明をアルゴリズムに適用しようとすると、さらに難しくなります。安定した(または十分に安定した)アルゴリズムにリファクタリングできるように、実際に代数を理解する必要があります。
私があなたなら、LAPACK/BLAS API をターゲットにして、あなたのデータ セットに適したライブラリを探し回ります。
LAPACK/BLAS、GSL、その他の自己最適化ライブラリ、ベンダー ライブラリなど、多くのオプションがあります。
私はこの図書館にあまりよく会いません。ただし、ライブラリは通常、パラメータでいくつかのテストを行うことを考慮する必要があります。ライブラリには、エラーに対する「通信のシステム」があり、関数を呼び出すときの新しい変数への帰属さえあります...計算が簡単な場合は、次のことができます。あなたの必需品に適応して、あなた自身でそれをやってみてください...