C ++よりも速い言語[非公開]
-
03-07-2019 - |
質問
Blitz ++は Fortranに近いパフォーマンスを提供すると言われています。
Fortranは、同等のタスクで実際に通常のC ++よりも高速になる傾向がありますか?
例外的な実行時パフォーマンスの他のHL言語はどうですか?特定のタスクでC ++を使用しない言語がいくつかあると聞きました... Objective Caml、Java、D ...
GCはスタックの周りに過剰なコピーをする必要をなくすので、多くのコードを高速化できると思いますか? (コードがパフォーマンスのために書かれているとは想定されていません)
私は好奇心を求めています-私は常に、C ++が専門のASMコーディングを除いてほとんど無敵だと思っていました。
解決
Fortranは、純粋に数値コードの場合、C ++よりも高速で、ほぼ常に優れています。 Fortranが高速である理由はたくさんあります。これは最も古いコンパイル済み言語です(コンパイラーの最適化に関する多くの知識)。依然として数値計算の言語であるため、多くのコンパイラベンダーは最適化されたコンパイラの販売で生計を立てています。他にも、より技術的な理由があります。 Fortran(少なくともFortran77)にはポインターがなく、したがって、そのドメインのC / C ++言語を悩ますエイリアシングの問題はありません。多くの高性能ライブラリは、Fortranでコーディングされており、長い(30年以上)歴史があります。 CとC ++のどちらにも適切な配列構造はありません(Cのレベルが低すぎる、C ++には地球上のコンパイラと同じ数の配列ライブラリがあり、それらはすべて互いに互換性がないため、十分にテストされた高速コードのプールを防ぎます)
他のヒント
Fortranがc ++よりも高速であるかどうかは議論の問題です。はいと言う人もいれば、ノーと言う人もいます。私はそれに行きません。コンパイラ、実行しているアーキテクチャ、アルゴリズムの実装などに依存します。
FortranがCに比べて優れている場合、これらのアルゴリズムを実装するのに時間がかかります。そのため、あらゆる種類の数値計算に非常に適しています。 Cに対する明らかな利点をいくつか説明します。
- 1ベースの配列インデックス(より大きなモデルを実装する際に非常に役立ちます。それについて考える必要はありませんが、 FORmula TRANslate
- パワー演算子(
**
)があります(神、パワー関数が実行するという考えを持ちましたか?演算子の代わりに!?) - それは、現在の市場のすべての言語の多次元配列に対する最良のサポートだと思います(そして、そうすぐに変わることはないようです)-
A(1,2)
数学のように - ループの回避は言うまでもありません-A = B * Cは配列を乗算します(ほぼコンパイル速度のmatlab構文のように)
- 言語に組み込まれた並列処理機能があります (この標準の新しい標準を確認してください)
- C、pythonなどの言語と非常に簡単に接続できるため、Fortranでヘビーデューティ計算を行うことができます。
- 完全な下位互換性があるため(F77全体がF90のサブセットであるため)、自由にコーディングを行うことができます。
- 非常に移植性が高い(これは一部のコンパイラ拡張機能では動作しない可能性がありますが、一般的には魅力のように動作します)
- 問題指向の解決コミュニティ(Fortranユーザーは通常csではなく、数学、物理学者、エンジニア...プログラミングのない人ですが、あなたの問題に関する知識が非常に高い問題解決経験があるため役立つ)
今、私の頭の上にある他のものは考えられないので、これはしなければなりません。
Blitz ++が競合しているのは、Fortran言語ではなく、Fortran数学ライブラリに費やされている何世紀もの仕事です。ある程度、この言語は役立ちます。古い言語は、最適化コンパイラを取得するのにより多くの時間を費やしました(そして、C ++は最も複雑な言語の1つです)。一方、 Blitz ++ や uBLAS を使用すると、比較的低レベルのFortranコードよりも明確に意図を述べることができます。まったく新しいクラスのコンパイル時最適化が可能になります。
ただし、ライブラリを常に効果的に使用するには、開発者が言語、ライブラリ、 数学に精通している必要があります。通常、次の3つのいずれかを改善することでコードを高速化できます...
FORTANは、言語が配列を実装する方法が異なるため、通常、配列処理に関してC ++よりも高速です。C++では可能ですが、FORTRANは配列要素のエイリアスを許可しません。これにより、FORTRANコンパイラーの作業が簡単になります。また、FORTRANには、50年近くにわたって取り組んできた非常に成熟した数学ライブラリが数多くあります。C++はそれほど長くはありませんでした!
これは、コンパイラー、プログラマー、それがgcを持っているかどうか、そして非常に異なる可能性があるかどうかに大きく依存します。マシンコードに直接コンパイルされている場合、ほとんどの場合に解釈されるよりも優れたパフォーマンスを期待しますが、とにかくasm速度を得る前に、有限量の最適化が可能です。
fortranがわずかに高速であると誰かが言った場合、とにかく新しいプロジェクトをコーディングしますか?
c ++の問題は、ハードウェアレベルに非常に近いことです。実際、ハードウェアレベルで(アセンブリブロックを介して)プログラムできます。一般的に、c ++コンパイラーは最適化でかなり良い仕事をします(巨大な速度向上のために、「リンクタイムコード生成」を有効にして、異なるcppファイル間の関数のインライン化を可能にします)。どうすれば、さらに高速に動作するいくつかの関数をアセンブリに書くことができます(ただし、コンパイラに勝てない場合もあります)。
独自のメモリマネージャー(他の多くの高レベル言語では許可されていないもの)を実装することもできます。したがって、特定のタスクに合わせてカスタマイズできます(ほとんどの割り当ては32バイト以下、次に、O(1)時間で割り当て/割り当て解除できる32バイトバッファの巨大なリストを作成できます)。使用しているコンパイラとハードウェアを完全に理解している限り、c ++は他の言語に勝ると信じています。その大部分は、どのアルゴリズムよりも多く使用するアルゴリズムに帰着します。
このページをロードするときは、奇妙なマネージXMLパーサーを使用する必要があります。 :)
私たちはコードを継続的にプロファイリングし、ゲインは一貫しています(そしてこれは素朴なC ++ではなく、ブーイングを備えた最新のC ++です)。少なくとも2倍、多くの場合5倍以上、CLR実装を一貫して舗装します。 Javaの20倍の速さだったJavaの日よりも少し優れていますが、良いインスタンスを見つけることができ、System.Objectの肥大化をすべて排除して、明らかにそれを打ち負かします。
マネージド開発者が得られないことの1つは、ハードウェアアーキテクチャがVMおよびオブジェクトルートアプローチのスケーリングに反対していることです。それを信じて、しばらく待ち、ブラウザを起動して、Silverlightのような「薄い」VMにアクセスするために、それを見る必要があります。あなたはそれがどれほど遅いか、そしてCPUが空腹であるかに驚かれることでしょう。
2つ、あらゆるパフォーマンスのためのデータベースアプリのキック、はい管理とネイティブデータベース。
数分前にこれを書きました:
通常、アルゴリズムは最終的なパフォーマンスを決定する言語ではなく、アルゴリズムです。
そのボールパーク内では、最適化コンパイラは通常、ほとんどのアセンブリコーダーよりも優れたコードを生成できます。
これは「常識」かもしれません。誰もがオウムできるが、おそらくそれが正しいからだと思う。反対の具体的な証拠を待っています。
Dは、実際のアプリケーションではC ++よりも高速になることがあります。これは、主にガベージコレクションの存在が、スマートポインターを使用する場合のRAIIおよび参照カウントのオーバーヘッドを回避するためです。自明ではないライフサイクルで大量の小さなオブジェクトを割り当てるプログラムの場合、ガベージコレクションはC ++スタイルのメモリ管理よりも高速です。また、Dの組み込み配列により、コンパイラーは、コンパイラーが理解できないC ++のSTLベクトルよりも優れた最適化を実行できる場合があります。さらに、D2は不変データと純粋な関数の注釈をサポートし、DMD2の最近のバージョンはそれに基づいて最適化します。 Dの作成者であるWalter Brightは、DとC ++の両方でJavaScriptインタープリターを作成しました。彼によると、Dバージョンの方が高速です。
すべてはコンパイラーに依存します。たとえば、スターリンスキームコンパイラーは、Debianマイクロベンチマークスイートのほぼすべての言語に勝っていますが、コンパイル時間について何か言及されていますか?
いいえ、ベンチマークのコンパイル(最大限の努力レベルでのすべての最適化)のためにコンパイルするのは(以前にスターリンを使用したことはありません)コードの最小部分以外は非常に長い時間がかかります。
コードがパフォーマンスのために書かれていない場合、 C#はC ++よりも高速です。
必要な免責事項:すべてのベンチマークは悪です。
これは、 C ++を支持するベンチマークです。 。
上記の2つのリンクは、C ++がC#より高速で、その逆の場合を見つけることができることを示しています。
コンパイルされた言語のパフォーマンスは役に立たない概念です。重要なのは、コンパイラの品質、つまりどの最適化を適用できるかです。たとえば、常にではありませんが、多くの場合、Intel C ++コンパイラはg ++よりもパフォーマンスの良いコードを生成します。それでは、C ++のパフォーマンスをどのように測定しますか?
言語のセマンティクスの出番は、プログラマーがコンパイラーに最適な出力を作成させるのがどれほど簡単かということです。たとえば、多くの場合、FortranコードはCコードよりも簡単に並列化できるため、Fortranは依然として高性能計算(気候シミュレーションなど)に頻繁に使用されています。
アセンブラーについての質問と回答のいくつか:同じことがここでも当てはまりますが、それは単なる別のコンパイルされた言語であり、したがって本質的に「高速」ではありません。アセンブラーと他の言語の違いは、理想的にはプログラムについて絶対的な知識を持っているプログラマーが、最適化の一部を「ダム」コンパイラーに委任するのではなく、すべての最適化を担当することです。
アセンブラの関数呼び出しでは、レジスタを使用して引数を渡すことができ、不要なスタックフレームを作成する必要はありませんが、優れたコンパイラでも同様に行うことができます(インライン化や高速呼び出しを考えてください)。アセンブラーを使用することの欠点は、パフォーマンスの良いアルゴリズムを実装するのが難しいことです(線形検索とバイナリ検索、ハッシュテーブル検索などを考えてください)。
C ++よりもはるかに良いことは、ほとんどの場合、コンパイラにプログラマの意味を理解させることです。この例としては、任意の言語のコンパイラーがコードの領域がその入力から独立しており、コンパイル時に結果値を計算するだけであると推測するインスタンスがあります。
これの別の例は、コンパイラが特定の呪文の「意味」を知っており、最高のパフォーマンスを生み出す実装を巧みに使用できるため、C#が非常に高いパフォーマンスのコードを生成する方法です。コンパイラはこのコードが提供する特定のケースではなく一般的なケースを処理しているため、不必要なalloc / deleteサイクル(テンプレートによって隠されています)。
最後の例は、もはやそれほどエキゾチックではないエキゾチックなハードウェア用に設計されたCのBrook / Cuda適応です。この言語は、コンパイル対象の非フォンニューマンハードウェアにマッピングされる正確なプリミティブ(カーネル関数)をサポートします。
それがなぜあなたがマネージドブラウザを使用しているのですか?速いからです。または、管理されたOSの方が高速です。いや、それはSQLデータベースです。待ってください、それはあなたがプレイしているゲームでなければなりません。やめて、JavaとCsharpは率直に言って役に立たない数値コードが必要です。ところで、ルート言語を遅らせるには、VMの記述内容を確認し、遅いと言う必要があります。
なんて勘違いなのでしょうが、高速管理アプリを見せてくれるので、みんな笑えます。 VS? OpenOffice?
C#はC ++よりもはるかに高速です。C#では、C ++を記述するのに10分の1の時間でXMLパーサーとデータプロセッサを記述できます。
ああ、実行速度のことですか?
それでも、コードの最初の行からコードの最初の実行の終わりまで時間をかけても、C#はおそらくC ++よりも高速です。
これは、C ++プログラムをC#に変換すること、およびC ++をC#より高速にするために必要な作業について非常に興味深い記事です。
したがって、開発速度を考慮すると、ほとんどすべてがC ++に勝ります。
OK、OPのランタイムのみのパフォーマンス要件に対処するには:言語ではなく、言語の実装がランタイムのパフォーマンスを決定します。想像できる最も遅いコードを生成するC ++コンパイラを作成できますが、それでもC ++です。また、理論的には、Java VMバイトコードではなくIA32命令をターゲットとするJava用のコンパイラを記述して、実行速度を向上させることもできます。
コードのパフォーマンスは、言語の長さとコードの要件の適合度に依存します。たとえば、C ++のGCベースのアロケーターは(C上記のリンクが表示されます)。文字列操作はC ++では遅くなりますが、php、perlなどの言語では速くなります。
ああ...古き良き質問-どのコンパイラがより高速なコードを作成しますか?
-
それは、実際に呼び出しスタックの下部で多くの時間を費やすコード、つまり、マトリックス反転などの関数呼び出しを含まないホットスポットでのみ重要です。
-
(1で実装)これは、コンパイラが実際に見るコードでのみ重要です。プログラムカウンタが、ビルドしていないサードパーティのライブラリですべての時間を費やしている場合、それは重要ではありません。
-
重要なコードでは、どのコンパイラがASMをより良くするかはすべて重要であり、それは主にソースコードがどれだけスマートに、または愚かに書かれているかによる関数です。
これらすべての変数では、優れたコンパイラを区別することは困難です。
ただし、前述のように、コンパイルするFortranコードがたくさんある場合は、書き直さないでください。