私はCプロジェクトの実行可能ファイルのサイズを縮小することを目指していましたが、すべてのコンパイラ/リンカーオプションを試しましたが、ある程度役に立ちました。私のコードはたくさんの別々のファイルで構成されています。私の質問は、すべてのソースコードを1つのファイルに結合することが、私が望む最適化に役立つかどうかでした。コンパイラーが、別々の複数のファイルではなく、単一のファイル内のすべてのコードを検出すると、コンパイラーがより適切に最適化されることをどこかで読みました。本当?
3 に答える
コンパイラーは、同じコンパイル可能な(* .c)ファイルで必要なコードを見つけると、実際に最適化を向上させることができます。プログラムが1000行程度より長い場合は、すべてのコードを1つのファイルに入れたことを後悔するでしょう。そうすると、プログラムの保守が難しくなりますが、500行より短い場合は、1つのファイルを試してみてください。それが役に立たないかどうかを確認してください。
重要な考慮事項は、あるコンパイル可能なファイルのコードが別のファイルで定義されたオブジェクト(関数を含む)を呼び出すか、使用する頻度です。この境界を越えて制御がほとんど移らない場合は、境界を消去してもパフォーマンスはそれほど向上しません。したがって、パフォーマンスのためにコーディングする場合、重要なのは、密接に関連するコードを同じファイルに入れることです。
私はあなたの質問がとても好きです。私の見解では、これは正しい種類の質問です。そして、完全な答えはStackexchangeの答えで完全に扱うのに十分単純ではありませんが、答えの追求はあなたに多くを教えてくれます。あなたはまだそれを理解していないかもしれませんが、あなたの質問は本当にリンクに関するものであり、すべての進歩するプログラマーが最終的に学ばなければならない主題です。あなたの質問は、シンボルテーブル、インライン化、戻り値のインプレース構築、およびその他のいくつかの微妙な要素に関するものです。
いずれにせよ、プログラムが500行程度より短い場合は、単一ファイルのアプローチを試して失うことはほとんどありません。1000行を超える場合は、単一のファイルはお勧めしません。
コンパイラによって異なります。たとえば、Intel C ++ Composer XEは、複数のファイルを自動的に最適化できます(Linux / Windowsの場合は、icc -fast *.c *.cpp
またはを使用してビルドする場合)。icl /fast *.c *.cpp
Microsoft Visual Studioまたは派生製品(マイクロコントローラー用のAtmel Studioなど)を使用する場合、すべての単一のソースファイルが独自にコンパイルされます(つまり、プロジェクト内のすべてのファイルに対して1つcl
、icl
またはgcc
コマンドが発行されます)。これは、最適化がないことを意味します。c
cpp
マイクロコントローラープロジェクトの場合、コントローラーの限られたフラッシュメモリに収まるようにするために、すべてを1つのファイルにまとめる必要がある場合があります。コンパイラー/IDEがVisualStudioのように動作する場合は、トリックを使用できます。すべてのソースファイルを選択し、ビルドプロセスに参加しないようにしてから(ただし、プロジェクトに残します)、ファイルを作成します(私は常にwhole_program.c
、を使用します。#include
その中のすべての単一のソース(つまり、非ヘッダー)ファイル(ファイルを含めることc
は多くの高レベルのプログラマーによって嫌われていることに注意してください、しかし時々、あなたはそれを汚い方法でやらなければなりません、そしてマイクロコントローラーでは、それは実際にはほとんどありません)。
私の経験では、gnu / gccを使用すると、最適化は単一のファイル内で行われ、さらに単一のオブジェクトを作成することが含まれます。clang / llvmを使用すると、非常に簡単です。clangステップを最適化せず、clangを使用してCからバイトコードに移行します。llvm-linkを使用してすべてのバイトコードモジュールを1つのバイトコードモジュールにリンクすると、最適化できます。プロジェクト全体、すべてのソースファイルが一緒に最適化され、llcはターゲットに向かうときにさらに最適化を追加します。最良の結果は、何かトリプルコマンドラインオプションを使用してclangに最終的なターゲットを伝えることです。gnuパスが同じことを行うには、includesを使用して1つの大きなファイルを1つのオブジェクトにコンパイルするか、リンカーが行ういくつかのこと以外にマシンコードレベルオプティマイザーがある場合は、それが発生する必要があります。多分gnuは公開されたirファイル形式を持っています、
http://github.com/dwelch67 私のプロジェクトの多くは、非常に単純なプログラムですが、同じソースファイルに対してllvmとgnuのビルドがありますが、最適化されていないバイトコードと最適化されたバイトコードからバイナリを作成するllvmビルドの場所を確認できます( llvmのオプティマイザーには小さなwhileループの問題があり、動作しないコードが生成されることがあります。最適化されていないllvmバイナリとgnuバイナリを試して、それらがすべて同じように動作するかどうかを確認するための非常に簡単なチェックです(あなた)または最適化されたllvmだけが機能しない場合(それら))。