3

これは珍しい質問ですが、決定的な答えがあることを願っています。

私たちのオフィスでは、コンパイラがどの程度効率的にコードを生成するか、具体的には命令数について、長年の議論があります。事実上ループのない低電力組み込みシステム用のコードを作成します。したがって、発行される命令の数は消費電力に正比例します。

私たちのコードの多くは次のようになります (注目、動的メモリ割り当てなし、システム コールなし、関数呼び出しはほとんどありません、ループはほとんどありません)。

foo += 3 * (77 + bar);
if (baz > 18 - qux)
    bar -= 19 + 7 >> spam;

上記のスニペットをコンパイルし-O3てアセンブリを読み取ることはできますが、自分で書くことはできませんでした。

私が証明または反証したい主張は、コンパイラが生成するコードは、手書きのアセンブリ コードと比較して 2 ~ 4 倍「太い」(したがって 2 ~ 4 倍の電力を消費する)ということです。

あなたが経験のあるコンパイラに興味があります。

この回答から、GCCとclangがCコードとインターリーブされたアセンブリを次のように出力できることがわかります

gcc -g -c -Wa,-alh foo.cc

これらの回答は、確固たる基盤を提供します。

アセンブリはいつ速くなりますか?

なぜアセンブリでプログラミングするのですか?

コンパイラがコードを生成する効率を測定するにはどうすればよいですか?

4

3 に答える 3

3

手作業によるアセンブリは、コンパイラに勝てない場合でも、常に少なくとも一致する可能性があります。これは、少なくとも、コンパイラが生成したアセンブリ コードから始めて、それを微調整してより良くすることができるためです。本当に良い仕事をするには、CPU アーキテクチャ (パイプライン、機能ユニット、メモリ階層、アウトオブオーダー ディスパッチ ユニットなど) を理解して、各命令を最大効率でスケジュールできるようにする必要があります。

考慮すべきもう 1 つの点は、命令の数は、速度であろうとパワーであろうと、必ずしもパフォーマンスに直接比例するとは限らないということです (Hennessey と Patterson のComputer Architecture: A Quantitative Approachを参照してください)。基本的に、命令の数 (およびクロック レート) に加えて、各命令にかかる時間を確認する必要があります。どれだけのエネルギーが消費されるかを知るには、各命令がどれだけのエネルギーを消費するかも知る必要があります。

CPU が各命令を実装する方法は、実行にかかるサイクル数に影響します。例として、コード シーケンスには>>演算子があります。コンパイラはそれを単一のASR命令に変換するかもしれませんが、アーキテクチャを知らなければ、何クロックサイクルかかるかわかりません.1サイクルで任意のシフトを実行できるアーキテクチャもあれば、ビットシフトごとに1サイクルを必要とするアーキテクチャもあります. .

メモリ アクセスも、サイクル数と消費電力に影響します。レジスタに格納する変数が多すぎる場合、そのうちのいくつかをメモリに格納する必要があります。オフチップ メモリにアクセスしていて、CPU クロック レートがかなり高い場合、メモリ バスはかなりの電力を消費する可能性があります。メモリからの読み取りとメモリへの書き込みを回避する (たとえば、同じ結果を 2 回計算することによって) より長い命令シーケンスは、より安価になる可能性があります。

他の何人かが示唆しているように、ベンチマークに代わるものはありません。一定の入力電圧でマイクロコントローラベースのシステムを使用していると仮定すると、最善の策は、代替コード セットごとにシステムの消費電流を測定し、どちらが最適かを確認することです (1 つの方法は、電流プローブとデジタル プローブを使用することです)。ストレージオシロスコープ)。

コンパイラよりも優れたアセンブラを常に記述できたとしても、開発時間と保守性にコストがかかります。The Mythical Man Monthで Brooks は、ほとんどではないにしても多くのプログラマーがアセンブラーでコードを書いていた時代に、 3倍から 5 倍の労力を費やしたと見積もっています。コードが非常に小さい場合を除き、アセンブリで最も重要な部分のみをコーディングするのが最善の方法です。それでも、アセンブリを作成する人は、実行中のコードと実行中のコードを比較することにより、(より高価な) コードがコストに見合うことを証明できるはずです。

于 2013-09-11T01:41:49.280 に答える
1

編集、楽しかったです...

コンパイラが人間よりも優れているという包括的な声明を出す人々は、実際にチェックしていない人々です. コンパイラが作成できるものはすべて、人間が作成できます。しかし、人間が作成できるコードをコンパイラが作成できるとは限りません。それはとても簡単です。数行から数十行以上のプロジェクトの場合、コンパイラーによって行われた最適化を手動で修正することがますます簡単になります。コンパイラとターゲットはそのギャップを埋めるのに役立ちますが、コンパイラの出力を満たすか超えることができる教育を受けた人が常にいます.

私が証明または反証したい主張は、コンパイラが生成するコードは、手書きのアセンブリ コードと比較して 2 ~ 4 倍「太い」(したがって 2 ~ 4 倍の電力を消費する)ということです。

「より太い」と定義していない限り、それだけの電力を使用することを意味します。バイナリのサイズと消費電力は関係ありません。この質問/プロジェクト全体が消費電力に関連している場合、コンパイラは、選択した BIOS 設定 (PC について話していると仮定)、ビデオ カード、ハードディスク、モニター、マウス、キーボードなどを考慮しません。方程式の1つの(比較的小さい)部分にすぎないプロセッサに加えて。そして、誰かがコードを効率的にするだけのコンパイラを作ったとしても、地球上のすべてのシステムに合わせてコンパイラを調整することはできませんし、そうするつもりもありません。起こらない。

非常に制御された環境である携帯電話について話している場合、アプリは電力を節約するために調整される可能性がありますが、コンパイラはそのマスターではなく、ユーザーであり、コンパイラはその一部を行い、残りは手動で調整されます。プログラマー。

I can compile the above snippet with -O3 and read the assembly, but I couldn't write it myself.

そのような態度でこれに入るなら、あなたは自動的に失敗しています。はい、コンパイラに会うか、打ち負かすことができます。それは自信と意志の力と時間/努力の問題です。このステートメントは、あなたがその問題を実際に研究していないことを意味します。時間をかけて、さらに調査を行い、stackoverflow で詳細な質問をしてください (このようなオープンエンドのものではありません)。時間の経過とともに、コンパイラーが行うことと行わないこと、およびその理由、特に完全ではない理由を理解することができます (いずれの場合も)。またはその意見を定義する多くの支配者)。この質問は完全に意見に関するものであり、炎上戦争を引き起こし、そのようなものは閉鎖され、最終的にこのサイトから削除されます. 代わりに、コード セグメントを作成、コンパイル、公開し、「

于 2013-09-11T00:57:29.487 に答える