12

この質問に完全に答えることは不可能であることは承知していますが、大まかな数値を求めているだけです。

妥当なサイズの C プログラム (数千行のコード) が与えられた場合、平均して生成される ASM 命令の数。言い換えれば、現実的な C と ASM の命令比率はどれくらいでしょうか? 「現在の x86 アーキテクチャで」など、自由に仮定してください。

これについてGoogleで調べてみましたが、何も見つかりませんでした。

補遺: この質問がどれほどの混乱を招いたかに気づき、説明が必要だと感じました。ヘルツあたりのスループットが、アーキテクチャ、ハードウェア、キャッシュ、バス速度、および月の位置によって大きく異なることは十分承知しています。

私は正確で科学的な答えを求めているのではなく、むしろ、計り知れないスケールに入れることができる経験的な答えを求めています.

これは場所に対する簡単な答えではありません (私が気づいたように)、これは私の最善の努力でした。C の行ごとに結果として得られる ASM の行の量は、何をしているかによって異なることを私は知っています。i++と同じ近隣にありませんsqrt(23.1)- 私はこれを知っています。さらに、C から取得した ASM に関係なく、ASM はプロセッサ内のさまざまなマイクロコードのセットに解釈されます。これは、AMD、Intel、またはその他のものを実行しているかどうか、およびそれぞれの世代によって異なります。これも承知しております。

私がこれまでに得た大まかな答えは、私が求めていたものです。ANSI-C の 1 行あたり x86 ASM の平均で約 2 行の十分な規模のプロジェクトです。今日のプロセッサは、パイプラインがいっぱいになり、十分な大きさのサンプルが与えられると、平均してクロック サイクルあたり約 1 つの ASM コマンドになるでしょう。

4

8 に答える 8

22

答えはありません。のようなステートメントint a;は、ゼロの asm 行を必要とする場合があります。while のようなステートメントには、20 行以上のa = call_is_inlined();asm 行が必要になる場合があります。

ac プログラムをコンパイルしてから を起動すると、自分自身を見ることができますobjdump -Sd ./a.out。asm と C コードが混在して表示されるので、1 つの C 行に対していくつの asm 行が生成されているかがわかります。例:

test.c

int get_int(int c);
int main(void) {
    int a = 1, b = 2;
    return getCode(a) + b;
}

$gcc -c -g test.c

$objdump -Sd ./test.o

00000000 <main>:
int get_int(int c);
int main(void) { /* here, the prologue creates the frame for main */
   0:   8d 4c 24 04             lea    0x4(%esp),%ecx
   4:   83 e4 f0                and    $0xfffffff0,%esp
   7:   ff 71 fc                pushl  -0x4(%ecx)
   a:   55                      push   %ebp
   b:   89 e5                   mov    %esp,%ebp
   d:   51                      push   %ecx
   e:   83 ec 14                sub    $0x14,%esp
    int a = 1, b = 2; /* setting up space for locals */
  11:   c7 45 f4 01 00 00 00    movl   $0x1,-0xc(%ebp)
  18:   c7 45 f8 02 00 00 00    movl   $0x2,-0x8(%ebp)
    return getCode(a) + b;
  1f:   8b 45 f4                mov    -0xc(%ebp),%eax
  22:   89 04 24                mov    %eax,(%esp)
  25:   e8 fc ff ff ff          call   26 <main+0x26>
  2a:   03 45 f8                add    -0x8(%ebp),%eax
} /* the epilogue runs, returning to the previous frame */
  2d:   83 c4 14                add    $0x14,%esp
  30:   59                      pop    %ecx
  31:   5d                      pop    %ebp
  32:   8d 61 fc                lea    -0x4(%ecx),%esp
  35:   c3                      ret
于 2008-12-01T17:04:48.423 に答える
12

「C命令」の意味がわかりません。おそらくステートメントまたは行ですか?もちろん、これは多くの要因によって大きく異なりますが、私自身のいくつかのサンプル プログラムを見た後、それらの多くは 2-1 マーク (LOC ごとに 2 つのアセンブリ命令) に近く、これが何であるかはわかりません。手段またはそれがどのように役立つか。

特定のプログラムと実装の組み合わせについて、コンパイラにアセンブリのみを生成するように要求するgcc -Sか (たとえば)、コンパイル済みの実行可能ファイルで逆アセンブラを使用することで、これを自分で把握できます (ただし、とにかくそれを比較するにはソース コードが必要です)。 .

編集

達成しようとしていることの明確化に基づいてこれを拡張するだけです(最新のプロセッサが1秒間に実行できるコードの行数を理解する):

最新のプロセッサは 1 秒あたり 30 億サイクルで実行できますが、1 秒あたり 30 億の命令を実行できるわけではありません。考慮すべき点は次のとおりです。

  • 多くの命令は、実行に複数のサイクルを要します (除算または浮動小数点演算は、実行に数十サイクルかかる場合があります)。
  • ほとんどのプログラムは、メモリ アクセスやディスク アクセスなどの待機に大部分の時間を費やしています。
  • OS のオーバーヘッド (スケジューリング、システム コールなど) を含む他の多くの要因も制限要因です。

しかし、一般的に、プロセッサは信じられないほど高速で、驚くべきことを短時間で達成できます。

于 2008-12-01T17:05:46.037 に答える
4

それは大きく異なります!彼らが大まかな変換を提供しようとしたとしても、私は誰も信じません.

のようなステートメントはi++;、単一の に変換できINC AXます。

多くのパラメーターを含む関数呼び出しのステートメントは、スタックが呼び出し用にセットアップされるため、数十の命令になる可能性があります。

次に、記述したものとは異なる方法でコードをアセンブルするコンパイラーの最適化を追加して、命令を削除します。

また、一部の命令は機械語境界でより適切に実行されるためNOP、コード全体に s が散りばめられます。

于 2008-12-01T17:00:17.170 に答える
3

ここでやろうとしていることから、実際のアプリケーションのパフォーマンスについて何も有益な結論を出すことはできないと思います。「正確でない」とは「数桁以内」を意味する場合を除きます。

あなたは非常に一般化されており、キャッシュなどを二次的なものであるかのように却下していますが、それは完全に支配的である可能性があります。

アプリケーションが十分に大きく、1つの場所あたりの平均的な命令数に傾向がある場合は、I / Oを発生させるのに十分な大きさであるか、少なくとも重要なRAMアクセスの問題を考慮に入れる必要があります。

于 2008-12-01T18:37:05.540 に答える
2

環境によっては、Visual Studio オプションを使用できます: /FAs

詳細はこちら

于 2008-12-01T18:08:29.247 に答える
1

RISCまたはCISC?とにかく、Cでの指示は何ですか?

これは、使用しているコードのタイプについて非常に具体的になるまで、実際にはわからない上記のポイントを繰り返すことです。

アセンブリの最適化と、過去30〜40年間に発生したハードウェア/ソフトウェア干渉のクロストークに関する学術文献を確認してみてください。ここで、関心のあるものに関するある種の実際のデータを見つけることができます(警告しますが、C->IA-32データではなくC->PDPデータが表示される可能性があります)。

于 2008-12-01T19:04:38.120 に答える
1

これに対する本当に有用な答えがあるかどうかはわかりません。確かに、アーキテクチャを選択する必要があります(提案したとおり)。

私ならどうするか: 妥当なサイズの C プログラムを用意します。gcc に「-S」オプションを指定して、自分で確認してください。アセンブラ ソース コードが生成され、そのプログラムの比率を自分で計算できます。

于 2008-12-01T17:02:44.217 に答える
1

あなたはコメントの 1 つに、3GHz の意味を知りたいと書いています。

CPUの周波数も関係ありません。最新の PC-CPU は、命令を頻繁にインターリーブおよびスケジュールし、フェッチおよびプリフェッチし、メモリと命令をキャッシュします。多くの場合、そのキャッシュは無効化されてビンに投げ込まれます。処理能力の最良の解釈は、実際のパフォーマンス ベンチマークを実行することによって得ることができます。

于 2011-08-09T06:21:51.940 に答える