18

私の経験では、.NET はネイティブ コードよりも 2 ~ 3 倍遅くなります。(多変量最適化のためにL-BFGSを実装しました)。

stackoverflow の広告を http://www.centerspace.net/products/まで追跡しました

スピードは本当に素晴らしく、スピードはネイティブコードに近いです。彼らはどのようにそれを行うことができますか? 彼らは言った:

Q. NMath は「純粋な」.NET ですか?

A. 答えは、「純粋な .NET」の定義によって多少異なります。NMath は、C# に加えて、小さなマネージ C++ レイヤーで記述されています。ただし、基本的な線形代数演算のパフォーマンスを向上させるために、NMath はネイティブの Intel Math Kernel Library (NMath に含まれています) に依存しています。しかし、COM コンポーネントや DLL はなく、.NET アセンブリだけです。また、マネージド C++ レイヤーで割り当てられ、ネイティブ コードで使用されるすべてのメモリは、マネージド ヒープから割り当てられます。

誰かが私にもっと説明できますか?

4

8 に答える 8

11

彼らはどのようにそれを行うことができますか?

.NET 用のほとんどの数値ライブラリと同様に、NMath は、おそらく C++/CLI とリンクして混合アセンブリを作成することにより、.NET アセンブリに埋め込まれた Intel MKL のラッパーにすぎません。おそらく、実際には .NET で記述されていないビットのベンチマークを行っただけでしょう。

F#.NET Journal の記事Numerical Libraries: special functions, interpolation and random numbers (2008 年 3 月 16 日) およびNumerical Libraries: linear algebra and Spectrum Methods (2008 年 4 月 16 日) では、かなりの機能がテストされましたが、NMath は実際にはすべての中で最も遅いものでした。商用ライブラリ。彼らの PRNG は他のすべてよりも遅く、無料の Math.NET ライブラリよりも 50% 遅く、いくつかの基本的な機能 (計算Gamma(-0.5)機能など) が欠けており、他の基本的な機能 (彼らが提供していたガンマ関連の関数) が壊れていました。Extreme Optimization と Bluebit の両方が、固有値ソルバー ベンチマークで NMath を上回りました。当時、NMath はフーリエ変換さえ提供していませんでした。

さらに驚くべきことに、パフォーマンスの不一致は時々大きくなりました。テストした最も高価な商用数値ライブラリ (IMSL) は、FFT ベンチマークで無料の FFTW ライブラリよりも 500 倍以上遅く、その時点でマルチコアを使用するライブラリはありませんでした。

実際、これらのライブラリの質の低さが、独自のF# for Numericsライブラリ (100% 純粋な F# コード) を商品化するきっかけとなったのです。

于 2010-07-02T18:40:11.680 に答える
10

私はILNumericsの主任開発者の 1 人です。だから私は明らかに偏っています;)しかし、私たちは内部に関してより開示されているのでスピードの「秘密」についていくつかの洞察を与えます.

すべては、システム リソースがどのように利用されるかにかかっています。純粋な速度が必要で、大規模な配列を処理する必要がある場合は、次のことを確認してください (重要度順、最も重要なものが最初)。

  1. 適切にメモリを管理してください!「素朴な」メモリ管理はパフォーマンスの低下につながります。これは、GC に過度のストレスを与え、メモリの断片化を引き起こし、メモリの局所性を低下させるためです (したがって、キャッシュ パフォーマンス)。.NET のようなガベージ コレクション環境では、これは要するに、頻繁なメモリ割り当てを防ぐことになります。ILNumerics では、この目標を達成するために高パフォーマンスのメモリ プールを実装しました (そして、不器用な関数セマンティクスのない適切で快適な構文を得るために一時配列を決定論的に破棄します)。

  2. 並列処理を活用!これは、スレッド レベルの並列処理とデータ レベルの並列処理の両方を対象としています。複数のコアは、計算の計算集約的な部分をスレッド化することによって利用されます。X86/X64 CPU では、SSE.XX や AVX などの SIMD/マルチメディア拡張により、小さいながらも効果的なベクトル化が可能になります。それらは、現在の .NET 言語では直接アドレス指定できません。これが、MKL が「純粋な」.NET コードよりも依然として高速である唯一の理由です。(しかし、ソリューションはすでに上昇しています。)

  3. FORTRAN や C++ などの高度に最適化された言語の速度を実現するには、コードに対して行ったのと同じ最適化をコードに適用する必要があります。C# はオプション do do so を提供します。

これらの予防措置は、この順序で実行する必要があることに注意してください。ボトルネックがメモリ帯域幅であり、プロセッサがほとんどの時間を新しいデータの待機に費やしている場合、SSE 拡張機能や境界チェックの削除を気にすることは意味がありません。また、多くの単純な操作では、最後の小さなスケールアップをピーク パフォーマンスまでアーカイブするために莫大な労​​力を投資しても報われません。LAPACK 関数 DAXPY の一般的な例を考えてみましょう。ベクトル X の要素を別のベクトル Y の対応する要素に追加します。これを初めて行う場合、X と Y のすべてのメモリをメイン メモリから取得する必要があります。それについてあなたができることはほとんどありません。そして、メモリがボトルネックです!したがって、最後の追加がC#で素朴な方法で行われたかどうかに関係なく

for (int i = 0; i < C.Length; i++) {
    C[i] = X[i] + Y[i]; 
}

またはベクトル化戦略を使用して行われます-メモリを待つ必要があります!

これらの戦略のほとんどは現在、言及された製品から(まだ?)使用されていないため、この回答は質問に対する「回答を超える」ことを知っています。これらの点に従うことで、最終的には「ネイティブ」言語でのすべての単純な実装よりもはるかに優れたパフォーマンスが得られます。

興味があれば、L-BFGS の実装を開示していただけますか? 喜んで ILNumerics に変換し、比較結果を投稿します。ここにリストされている他のライブラリも従いたいと思います。(?)

于 2012-02-17T12:12:13.160 に答える
8

C++/CLI に関する点は正しいです。全体像を完成させるために、興味深い点を 2 つだけ追加します。

  • .NET メモリ管理 (ガベージ コレクター) は明らかにここでは問題ではありません。NMath は依然としてそれに依存しているためです。

  • パフォーマンス上の利点は、多くの CPU に最適化された実装を提供するインテル® MKL によって実際に提供されます。私の観点からすると、これが重要なポイントです。単純明快な C/C++ コードを使用しても、必ずしも C#/.NET より優れたパフォーマンスが得られるとは限りません。ただし、C++/CLI を使用すると、すべての「汚い」最適化オプションを活用できます。

于 2009-12-02T08:51:47.907 に答える
5

この質問に対処するブログ記事を投稿しました。

于 2009-12-21T20:43:54.693 に答える
3

キーはC++/CLIです。C++ コードをマネージ .NET アセンブリにコンパイルできます。

于 2009-12-02T08:29:52.687 に答える
2

今日では、両方のプラットフォームを利用してパフォーマンスを最適化するために、混合 .Net/native ライブラリを作成することが業界標準になっています。NMath だけでなく、.net インターフェイスを備えた多くの商用および無料のライブラリがこのように機能します。例: Math.NET Numerics、dnAnalytics、Extreme Optimization、FinMathなど。MKL との統合は .net 数値​​ライブラリで非常に人気があり、そのほとんどはマネージド C++ アセンブリを中間レベルとして使用するだけです。ただし、このソリューションにはいくつかの欠点があります。

  1. Intel MKL はプロプライエタリ ソフトウェアであり、少し高価です。ただし、dnAnalytics などの一部のライブラリでは、MKL 機能を純粋な .net コードに無料で置き換えることができます。もちろん、はるかに遅くなりますが、無料で完全に機能します。

  2. これにより、32 ビット モードと 64 ビット モードの両方で重いマネージド C++ カーネル dll が必要になるため、互換性が低下します。

  3. 管理からネイティブへの呼び出しでは、ガンマや NormalCDF などの高速で頻繁に呼び出される操作のパフォーマンスを低下させるマーシャリングを実行する必要があります。

RTMath FinMath ライブラリで解決された最後の 2 つの問題。彼らがどのようにそれを行ったのかはよくわかりませんが、Any CPU プラットフォーム用にコンパイルされ、32 ビットと 64 ビットをサポートする単一の純粋な .net dll を提供しています。また、NormalCDF を何十億回も呼び出す必要がある場合でも、MKL に対するパフォーマンスの低下は見られませんでした。

于 2011-11-04T20:40:52.473 に答える
1

(ネイティブの) インテル® MKL が計算を行っているため、実際にはマネージ コードで計算を行っているわけではありません。.Net のメモリ マネージャーを使用しているだけなので、結果は .Net コードで簡単に使用できます。

于 2009-12-02T11:23:09.803 に答える