89

そこにいるすべての筋金入りの低レベルのハッカーに質問があります。私はブログでこの文に出くわしました。それは一般的な声明のように思われるので、私はソースが重要であるとは思いません(あなたが本当に気にかけているならそれはHaackです)。

たとえば、最近の多くの3Dゲームには、C++およびアセンブリで記述された高性能コアエンジンがあります。

アセンブリに関する限り、コンパイラが余分な命令を発行したり、過剰なバイトを使用したりすることを望まないため、またはCで表現できない(またはなしで表現できない)より優れたアルゴリズムを使用しているため、アセンブリで記述されたコードです。コンパイラはそれらを混乱させます)?

低レベルのものを理解することが重要だと完全に理解しています。あなたがそれを理解した後、私はアセンブリのなぜプログラムを理解したいだけです。

4

30 に答える 30

172

私はあなたがこの声明を誤解していると思います:

たとえば、最新の 3D ゲームの多くは、C++ およびアセンブリで記述された高性能コア エンジンを備えています。

ゲーム (および最近のほとんどのプログラム) は、「C++ で書かれている」のと同じように「アセンブリで書かれている」わけではありません。そのブログは、ゲームの大部分がアセンブリで設計されているとか、プログラマーのチームが座ってアセンブリを主要言語として開発していると言っているのではありません。

これが実際に意味することは、開発者が最初にゲームを作成し、それを C++ で動作させるということです。次に、それをプロファイリングし、ボトルネックが何であるかを把握し、それが価値がある場合は、アセンブリでそれらを最適化します。または、すでに経験を積んでいる場合は、どの部分がボトルネックになるかを知っており、構築した他のゲームから最適化された部分を持っています.

アセンブリでのプログラミングのポイントは、これまでと同じです:速度. アセンブラーで大量のコードを書くのはばかげていますが、コンパイラーが認識していない最適化がいくつかあり、コードのウィンドウが十分に小さい場合は、人間の方がうまくいくでしょう。

たとえば、浮動小数点の場合、コンパイラはかなり保守的である傾向があり、アーキテクチャのより高度な機能の一部を認識していない可能性があります。ある程度のエラーを許容できる場合は、通常、コンパイラよりも優れた処理を行うことができます。多くの時間が費やされる場合は、アセンブリにその小さなコードを記述する価値があります。

より関連性の高い例を次に示します。

ゲームからの例

  • SSE 組み込み関数を使用したゲーム エンジンの最適化に関するIntel の記事。最終的なコードは組み込み関数 (インライン アセンブラーではない) を使用するため、純粋なアセンブリの量は非常に少なくなります。しかし、彼らはコンパイラによるアセンブラ出力を見て、何を最適化すべきかを正確に判断します。

  • Quake の高速逆平方根. 繰り返しになりますが、このルーチンにはアセンブラーは含まれていませんが、この種の最適化を行うには、アーキテクチャについてある程度知っておく必要があります。作成者は、どの演算が高速で (乗算、シフト)、どの演算が低速であるか (除算、平方根) を知っています。そこで彼らは、遅い操作を完全に回避する非常にトリッキーな平方根の実装を考え出しました。

高性能コンピューティング

  • ゲームの領域外では、科学計算に携わる人々は、最新のハードウェアで高速に動作するように最適化することがよくあります。これは、物理学をごまかすことができないゲームと考えてください。

    これの最近の素晴らしい例は、格子量子色力学 (格子 QCD)です。 この論文では、この問題が、 IBM Blue Gene/L上の PowerPC 440 向けに大幅に最適化された 1 つの非常に小さな計算カーネルに要約される方法について説明しています。各 440 には 2 つの FPU があり、コンパイラが悪用するのが難しい特殊な 3 項演算をサポートしています。これらの最適化がなければ、Lattice QCD の実行速度は非常に遅くなり、問題が高価なマシンで何百万もの CPU 時間を必要とする場合、コストがかかります。

    なぜこれが重要なのか疑問に思っている場合は、この研究から生まれたScienceの記事をチェックしてください。格子 QCD を使用して、彼らは第一原理から陽子の質量を計算し、昨年、質量の 90% が強力な結合エネルギーから来ており、残りがクォークから来ていることを示しました。これがE=mc 2の動作です。 ここに要約があります。

上記のすべてについて、アプリケーションは100% アセンブリで設計または記述されているわけではありません。しかし、本当にスピードが必要な場合は、特定のハードウェアで動作するようにコードの主要部分を書くことに集中します。

于 2009-04-26T21:51:42.717 に答える
43

私は何年もアセンブリ言語でコーディングしていませんが、私が頻繁に見たいくつかの理由を挙げられます。

  • すべてのコンパイラが特定のCPU最適化と命令セット(たとえば、Intelが時々追加する新しい命令セット)を利用できるわけではありません。コンパイラの作成者が追いつくのを待つことは、競争上の優位性を失うことを意味します。

  • 実際のコードを既知のCPUアーキテクチャおよび最適化に簡単に一致させることができます。たとえば、フェッチメカニズム、キャッシングなどについて知っていること。これは開発者には透過的であると想定されていますが、実際にはそうではないため、コンパイラの作成者は最適化できます。

  • 特定のハードウェアレベルのアクセスは、アセンブリ言語を介してのみ可能/実用的です(たとえば、デバイスドライバーを作成する場合)。

  • コードの最終またはほぼ最終的なレイアウトが何であるかをすでに知っているので、正式な推論は、高水準言語よりもアセンブリ言語の方が実際に簡単な場合があります。

  • APIを使用せずに特定の3Dグラフィックカード(1990年代後半頃)をプログラミングすることは、アセンブリ言語ではより実用的かつ効率的であることが多く、他の言語では不可能な場合もありました。しかし、繰り返しになりますが、これには、データを特定の順序で手動で出し入れするなど、アクセラレータアーキテクチャに基づく本当にエキスパートレベルのゲームが含まれていました。

高級言語が使用する場合、特にその言語がCの場合、多くの人がアセンブリ言語を使用するのではないかと思います。大量の汎用コードを手動で最適化することは実用的ではありません。

于 2009-04-26T20:25:32.533 に答える
19

アセンブラ プログラミングには、他の人が言及していない 1 つの側面があります。それは、アプリケーション内のすべてのバイトが、コンパイラではなく自分自身の努力の結果であることを知って得られる満足感です。80 年代初頭に行っていたように、アプリ全体をアセンブラーで作成することに一瞬たりとも戻りたくありませんが、時々その感覚が恋しくなります...

于 2009-04-26T20:32:40.347 に答える
18

通常、素人のアセンブリはCよりも低速です(Cの最適化のため)が、多くのゲーム(Doomをはっきりと覚えています)は、通常のマシンでスムーズに実行できるように、ゲームの特定のセクションをアセンブリに含める必要がありました。

これが私が参照している例です。

于 2009-04-26T20:24:45.750 に答える
11

"はい"。ただし、ほとんどの場合、アセンブラーでコードを記述する利点は、努力する価値がないことを理解してください。アセンブリでそれを書くことで得られる見返りは、問題についてもっと真剣に考え、物事を行うためのより良い方法を考えることに時間を費やすことに集中するよりも小さくなる傾向があります。

John Carmack と Michael Abrash は、Quake と、ID ゲーム エンジンに組み込まれたすべての高性能コードの作成に主に責任を負いまし

また、Ólafur Waage の意見にも同意します。今日のコンパイラは非常にスマートであり、多くの場合、隠れたアーキテクチャ上のブーストを利用する多くの手法を採用しています。

于 2009-04-26T20:29:04.427 に答える
10

最近では、少なくともシーケンシャル コードの場合、まともなコンパイラは、経験豊富なアセンブリ言語プログラマでさえ、ほぼ常に打ち負かしています。しかし、ベクトル コードの場合は別の話です。たとえば、広く展開されているコンパイラは、x86 SSE ユニットのベクトル並列機能を活用して、それほど優れた仕事をしません。私はコンパイラーのライターであり、SSE を利用することは、コンパイラーを信頼するのではなく、自分でやるべき理由のリストのトップです。

于 2009-04-27T01:59:39.127 に答える
8

SSE コードは、少なくとも MSVC では、コンパイラ組み込み関数よりもアセンブリでうまく機能します。(つまり、データの余分なコピーを作成しません)

于 2009-04-26T20:36:35.127 に答える
6

作業中のソースには、3 つまたは 4 つのアセンブラー ルーチン (約 20 MB のソース) があります。それらはすべてSSE(2)であり、(かなり大きい - 2400x2048 以上と考えてください) 画像の操作に関連しています。

趣味でコンパイラをやっていますが、そこにはアセンブラがあります。ランタイム ライブラリは非常に多くの場合、それらでいっぱいです。それらのほとんどは、通常の手続き体制に反するもの (例外のヘルパーなど) に関係しています。

マイクロコントローラー用のアセンブラーがありません。最近のほとんどのマイクロコントローラーには、非常に多くの周辺ハードウェア (割り込み制御カウンター、さらには直交エンコーダーやシリアル ビルディング ブロック全体) が含まれているため、アセンブラーを使用してループを最適化する必要がなくなることがよくあります。現在のフラッシュの価格では、同じことがコード メモリにも当てはまります。また、多くの場合、ピン互換性のあるデバイスの範囲があるため、CPU 電力またはフラッシュ スペースが体系的に不足している場合のアップスケーリングは、多くの場合問題になりません。

実際に 100000 個のデバイスを出荷しない限り、プログラミング アセンブラを使用すると、フラッシュ チップを 1 カテゴリ小さくするだけで大​​幅な節約が可能になります。しかし、私はその範疇ではありません。

多くの人は、組み込みはアセンブラの言い訳だと考えていますが、彼らのコントローラはUnixが開発されたマシンよりも多くの CPU パワーを持っています。(Microchip には 40 および 60 MIPSのマイクロコントローラーが付属しており、10米ドル未満で提供されています)。

しかし、マイクロチップのアーキテクチャを変更するのは簡単ではないため、多くの人がレガシーに固執しています。また、HLL コードはアーキテクチャに大きく依存します (ハードウェア周辺機器、レジスタを使用して I/O を制御するためなど)。そのため、プロジェクトをアセンブラーで維持し続ける正当な理由が時々あります (私は幸運にも、新しいアーキテクチャーをゼロからセットアップすることができました)。しかし、多くの場合、本当にアセンブラが必要だと自分をからかっています。

GOTO を使用できるかどうか尋ねたときの教授の答えは今でも気に入っています (ただし、これは ASSEMBLER と読むこともできます) 。 . 結果とともにエッセイを提出してください。

私はそれを低レベル機能の指針として使用しました。窮屈すぎて使用することはできませんが、適切に動機付けするようにしてください。正当化としての複雑な推論を避けるために、人為的な障壁 (エッセイなど) を 1 つまたは 2 つ投げることさえできます。

于 2009-05-08T08:23:59.047 に答える
5

欠陥は行ごとに実行される傾向があります(ステートメント、コードポイントなど)。ほとんどの問題では、アセンブリは高級言語よりもはるかに多くの行を使用することは事実ですが、目前の問題に最も適した(最も簡潔で最も少ない行)マップである場合があります。これらのケースのほとんどは、組み込みシステムでのドライバーやビットバンギングなどの通常の容疑者に関係しています。

于 2009-04-27T02:19:29.967 に答える
5

一部の命令/フラグ/制御は、C レベルにはありません。

たとえば、x86 でのオーバーフローのチェックは単純なオーバーフロー フラグです。このオプションは C では使用できません。

于 2009-04-26T22:29:21.923 に答える
3

128バイトのRAMと4Kのプログラムメモリを備えたローエンドの8ビットマイクロコントローラをプログラミングしている場合、アセンブリを使用することについて多くの選択肢はありません。ただし、より強力なマイクロコントローラーを使用する場合は、正確な時間に特定のアクションを実行する必要がある場合があります。命令を数え、コードで使用されるクロックサイクルを測定できるため、アセンブリ言語が役立ちます。

于 2009-04-28T08:47:44.987 に答える
3

2000 年問題のすべての修正作業に参加していた場合、Assembly のことを知っていれば、大金を稼げたはずです。その中に書かれたレガシーコードがまだたくさんあり、そのコードは時々メンテナンスが必要です。

于 2009-04-26T20:28:17.910 に答える
3

もう 1 つの理由は、利用可能なコンパイラがアーキテクチャに対して十分ではなく、プログラムに必要なコードの量が、プログラマが迷子になるほど長くも複雑でもない場合です。組み込みシステム用のマイクロコントローラーをプログラミングしてみてください。通常、組み立てははるかに簡単です。

于 2009-04-26T20:32:49.007 に答える
3

言及された他の事柄に加えて、すべての高等言語には特定の制限があります。そのため、コードを完全に制御するために、ASM でプログラミングすることを選択する人もいます。

他の人は、20〜60KBの範囲の非常に小さな実行可能ファイルを楽しんでいます。たとえば、 HiEditor コントロールの作成者によって実装されているHiEditorを確認してください。これは、構文の強調表示とタブをわずか〜50kbで備えたWindows用の優れた強力な編集コントロールです。私のコレクションには、Excell のような ssheets から html レンダリングまで、20 以上のゴールド コントロールがあります。

于 2009-04-26T20:39:10.707 に答える
2

アセンブリの使用について個人的に話した開発者は 1 人だけです。彼は、ポータブル mp3 プレーヤーの制御を扱うファームウェアに取り組んでいました。アセンブリでの作業には 2 つの目的がありました。

  1. 速度: 遅延を最小限に抑える必要がありました。
  2. コスト: コードを最小限に抑えることで、それを実行するために必要なハードウェアの性能がわずかに低下する可能性があります。何百万ものユニットを大量生産する場合、これは合計される可能性があります。
于 2009-07-24T16:51:25.963 に答える
2

これまでに見た中規模から大規模のゲーム エンジンまたはライブラリのほぼすべてには、4x4 行列連結などの行列演算に使用できる手動で最適化されたアセンブリ バージョンがいくつかあります。大規模な行列を処理する場合、コンパイラは必然的にいくつかの巧妙な最適化 (レジスタの再利用、最大限に効率的な方法でのループの展開、マシン固有の命令の利用など) を見落としているようです。これらのマトリックス操作関数は、ほとんどの場合、プロファイル上でも「ホットスポット」です。

また、カスタム ディスパッチに多く使用される手作業でコード化されたアセンブリも見てきました。FastDelegate のようなものですが、コンパイラとマシン固有のものです。

最後に、割り込みサービス ルーチンがある場合、asm は世界ですべての違いを生むことができます。割り込み中に発生させたくない特定の操作があり、割り込みハンドラーを "取得および取得" する必要があります。 .. asm の場合、ISR で何が起こるかをほぼ正確に知っているため、血まみれのことを短く保つことができます (とにかく良い習慣です)。

于 2009-04-28T22:43:38.503 に答える
2

非常に小さな CPU での非常に小さなプロジェクトは別として、アセンブリでプロジェクト全体をプログラムするつもりはありません。ただし、パフォーマンスのボトルネックは、一部の内部ループを戦略的に手動でコーディングすることで解消できることがよくあります。

場合によっては、オプティマイザが使用方法を理解することが期待できない言語構造を命令に置き換えるだけで本当に必要になることがあります。典型的な例は、ベクトル演算と積和演算がオプティマイザーにとって発見しにくい DSP アプリケーションにありますが、コードを渡すのは簡単です。

たとえば、SH4 の特定のモデルには、4x4 マトリックスと 4 つのベクトル命令が含まれています。ハードウェアの仮定に一致するように補正行列を 4x4 に拡大するわずかなコストで、3x3 行列に対する同等の C 演算を適切な命令に置き換えることで、色補正アルゴリズムのパフォーマンスが大幅に向上することを確認しましたこれは、12 行以下のアセンブリを記述し、関連するデータ型とストレージに一致する調整を周囲の C コードのいくつかの場所に実行することによって達成されました。

于 2009-04-27T00:09:02.887 に答える
2

言及されていないようなので、追加しようと思いました。最近のゲーム開発では、書かれているアセンブリの少なくとも一部は CPU 用ではないと思います。シェーダー プログラムの形式で、GPU 用です。

これは、あらゆる種類の理由で必要になる場合があります。場合によっては、使用される高レベルのシェーディング言語が、サイズの制約、速度、または任意の組み合わせに適合するために、必要な命令の正確な数で正確な操作を表現できないためです。 . アセンブリ言語プログラミングと同じように、私は推測します。

于 2009-04-28T09:01:11.553 に答える
2

私が続けている唯一のアセンブラ コーディングは、リソースが乏しい組み込みハードウェア向けのものです。リーダーが言及しているように、アセンブリは、コードが高速でよく理解されている必要があるISRに依然として適しています。

2 つ目の理由は、アセンブリに関する知識を維持することです。CPU が自分の命令を実行するために実行している手順を調べて理解できることは、気分がいいものです。

于 2009-05-04T18:41:09.767 に答える
1

私は数年間アセンブリで書いていませんが、以前は次の 2 つの理由で書いていました。

  • ものへの挑戦!私は何年も前にx86 アセンブリですべてを書いていた数か月の期間を経験しました( DOSと Windows 3.1 の時代)。基本的に、低レベルの操作、ハードウェアI/Oなどのチャンクを教えてくれました。
  • いくつかのことについては、サイズを小さく保ちました (ここでも、TSRを書くときの DOS とWindows 3.1 ) 。

コーディング アセンブリをもう一度見続けていますが、それは挑戦と喜びに他なりません。他にそうする理由はありません:-)

于 2009-10-25T21:36:25.890 に答える
1

私がGCCと Visual C++ 2008 (Visual C++ 9.0 としても知られています) よりも優れたパフォーマンスを発揮できれば、人々はそれがどのように可能かについて私にインタビューすることに興味を持つでしょう。

これが、当面、アセンブリで物事を読み取り、必要に応じて __asm int 3 を記述する理由です。

これが助けになることを願っています...

于 2009-10-21T19:58:50.440 に答える
0

Android フォンで Java アプリケーションのバイトコードを解釈する Dalvik VM は、ディスパッチャにアセンブラを使用します。このムービー(約 31 分ですが、ムービー全体を見る価値があります!) では、その方法を説明しています。

「人間がコンパイラよりもうまくできる場合がまだあります」。

于 2010-01-15T08:50:57.487 に答える
0

私はそうではありませんが、少なくとも試して、将来のある時点で一生懸命努力することをポイントにしています(できればすぐに)。高水準言語でプログラミングをしているときに、低水準のことや、舞台裏で物事がどのように機能するかをもっと知ることは悪いことではありません。残念ながら、開発者/コンサルタント、および親としてのフルタイムの仕事をしていると、時間を確保するのは困難です。しかし、私はやがて与えます、それは確かです.

于 2010-01-15T08:55:42.780 に答える