gccコンパイルおよび最適化ガイド

CFLAGSおよびCXXFLAGS

CFLAGSはCコンパイラのオプションを表し、CXXFLAGSはC ++コンパイラのオプションを表します。これらの2つの変数は、実際にはコンパイルとアセンブリの2つのステップをカバーしています。ほとんどのプログラムとライブラリは、デフォルトの最適化レベル「2」(「-O2」オプションを使用)でコンパイルされ、デバッグシンボル、つまりCFLAGS = "-O2 -g"、CXXFLAGS = $ CFLAGSでコンパイルされます。実際、「-O2」はすでにほとんどの安全な最適化オプションを有効にしています。一方、ほとんどのオプションはこれら2つの変数に同時に使用できるため、最後に1つの変数にのみ使用できるオプションについてのみ説明します。[リマインダー]以下のオプションはすべてデフォルト以外の オプションです。必要に応じて追加する必要があります。

「-O2」に基づく「-O3」の追加についてお話しします。

-finline-関数

コンパイラがいくつかの単純な関数を選択して、それらが呼び出された場所で展開できるようにします。これは、特にCPUの第2レベルのキャッシュが大きい場合に、より安全なオプションです。

-funswitch-loops

値を変更しない変数をループ本体の外に移動します。

-fgcse-after-reload

過剰なオーバーフローをクリアするために、リロード後に追加の負荷除去ステップが実行されます。

加えて:

-fomit-frame-pointer

スタックポインタを必要としない関数の場合、ポインタはレジスタに格納されないため、アドレスを格納および取得するためのコードは無視でき、多くの関数に追加のレジスタが提供されます。すべての「-O」レベルでオンになりますが、スタックポインターに依存せずにデバッガーを実行できる場合にのみ機能します。このオプションは、AMD64プラットフォームではデフォルトでオンになっていますが、x86プラットフォームではデフォルトでオフになっています。明示的に設定することをお勧めします。

-falign-functions = N
-falign-jumps = N
-falign-loops = N
-falign-labels = N

これらの4つの配置オプションは「-O2」でオンになっており、その中で、プラットフォームに応じてNには異なるデフォルト値が使用されます。デフォルト値とは異なるNを指定する場合は、個別に指定することもできます。たとえば、L2-cache> = 1MのCPUの場合、-falign-functions = 64を指定すると、パフォーマンスが向上する可能性があります。-marchが指定されている場合は、ここで値を明示的に指定しないことをお勧めします。

デバッグオプション:

-fprofile-arcs

このオプションを使用してプログラムをコンパイルし、実行して各コードブロックの実行回数を含むファイルを作成した後、プログラムを-fbranch-probabilitiesで再度コンパイルし、ファイル内の情報を使用して、頻繁に選択されるものを最適化できます。ブランチ。この情報がないと、gccは最適化のためにどのブランチが頻繁に実行されるかを推測します。このような最適化情報は、ソースファイルの名前と接尾辞「.da」が付いたファイルに保存されます。

グローバルオプション:

-パイプ

コンパイルプロセスのさまざまな段階間の通信に一時ファイルの代わりにパイプを使用すると、コンパイルを高速化できます。使用をお勧めします。

ディレクトリオプション:

--sysroot =あなた

論理ルートディレクトリとしてdirを使用します。たとえば、コンパイラは通常、/ usr / includeおよび/ usr / libでヘッダーファイルとライブラリを検索します。このオプションを使用すると、dir / usr / includeおよびdir / usr / libディレクトリで検索されます。-isysrootオプションの使用中にこのオプションを使用する場合、このオプションはライブラリファイルの検索パスにのみ適用され、-isysrootオプションはヘッダーファイルの検索パスに適用されます。このオプションは最適化とは関係ありませんが、CLFSでは魔法のような効果があります。

コード生成オプション:

-fno-bounds-check

配列アクセスのすべての境界チェックをオフにします。このオプションを使用すると、配列のインデックス作成のパフォーマンスが向上しますが、配列の境界を超えると、許容できない動作が発生する可能性があります。

-freg-struct-return

構造体と共用体がレジスタを介して戻るのに十分小さい場合、これにより、より小さな構造体の効率が向上します。レジスタに収まるほど小さくない場合は、メモリを使用して戻ります。GCCでコンパイルされたシステムでのみ使用することをお勧めします。

-fpic

共有ライブラリで使用できる位置に依存しないコードを生成します。すべての内部アドレス指定は、グローバルオフセットテーブルを介して行われます。アドレスを決定するには、コード自体のメモリ位置をアイテムとしてテーブルに挿入する必要があります。このオプションは、共有ライブラリに格納およびロードできるオブジェクトモジュールを生成します。

-fstack-check

プログラムスタックオーバーフローを防ぎ、必要な検出を実行するために、マルチスレッド環境で実行している場合にのみ必要になる場合があります。

-fvisibility = hidden

デフォルトのELFミラーのシンボルの可視性を非表示に設定します。この機能を使用すると、共有ライブラリのリンクとロードのパフォーマンスを完全に向上させ、より最適化されたコードを生成し、ほぼ完全なAPI出力を提供し、シンボルの衝突を防ぐことができます。共有ライブラリをコンパイルするときは、このオプションを使用することを強くお勧めします。-fvisibility-inlines-hiddenオプションを参照してください。

ハードウェアアーキテクチャ関連のオプション[x86およびx86_64のみ]:

-march = cpu-type

特定のCPUタイプのバイナリコードをコンパイルします(下位レベルのCPUでは実行できません)。Intelが使用できるもの:pentium2、pentium3(= pentium3m)、pentium4(= pentium4m)、pentium-m、prescott、nocona、core2(GCC-4.3の新機能)。AMDが使用できるもの:k6-2(= k6-3)、athlon(= athlon-tbird)、athlon-xp(= athlon-mp)、k8(= opteron = athlon64 = athlon-fx)

-mfpmath = sse

P3およびathlon-xpレベル以上のCPUは、「sse」スカラー浮動小数点命令をサポートします。このオプションは、P4およびK8より上のプロセッサーでのみ使用することをお勧めします。

-悪性ダブル

double、long double、およびlong longを2バイト境界に揃えます。より高速なコードを生成すると便利ですが、プログラムのサイズが大きくなり、このオプションなしでコンパイルされたプログラムでは機能しません。

-m128bit-long-double

long doubleを128ビットとして指定します。pentiumを超えるCPUはこの標準を優先し、x86-64のABI標準に準拠していますが、i386のABI標準には準拠していません。

-mregparm = N

整数パラメーターを渡すために使用されるレジスターの数を指定します(レジスターはデフォルトでは使用されません)。0 <= N <= 3;注:N> 0の場合、すべてのライブラリーを含むすべてのモジュールを同じパラメーターで再構築する必要があります。

-msseregparm

SSEレジスタを使用して、floatおよびdoubleパラメータと戻り値を渡します。注:このオプションを使用した後は、すべてのライブラリーを含むすべてのモジュールを同じパラメーターで再構築する必要があります。

-mmmx
-msse
-msse2
-msse3
-m3dnow
-mssse3(はい!GCC-4.3新規)
-msse4.1(GCC-4.3新規)
-msse4.2(GCC-4.3新規)
-msse4(4.1および4.2を含む、GCC- 4.3新規)

対応する拡張命令セットと組み込み関数を使用するかどうかは、独自のCPUに応じて選択してください。

-maccumulate-outgoing-args

関数bootセクションで出力パラメーターの計算に必要な最大スペースを指定します。これは、ほとんどの最新のCPUでより高速な方法です。欠点は、バイナリファイルのサイズが大幅に増加することです。

-mthreads

Mingw32のスレッドセーフな例外処理をサポートします。スレッドセーフな例外処理に依存するプログラムの場合、このオプションを有効にする必要があります。このオプションを使用すると、「-D_MT」が定義され、各スレッドの例外処理データをクリーンアップするためのオプション「-lmingwthrd」に接続された特別なスレッド補助ライブラリが含まれます。

-minline-all-stringops

デフォルトでは、GCCは、宛先が少なくとも4バイトの境界に整列されることを決定する文字列操作のみをプログラムコードにインライン化します。このオプションを使用すると、バイナリファイルのインライン化とサイズの増加が可能になりますが、高速memcpy、strlen、およびmemset操作に依存するプログラムのパフォーマンスを向上させることができます。

-minline-stringops-動的に

GCC-4.3の新機能。サイズが不明な文字列の小さなブロック操作にはインラインコードを使用し、大きなブロック操作にはライブラリ関数を呼び出します。これは「-minline-all-stringops」よりも賢い戦略です。戦略を決定するためのアルゴリズムは、「-mstringop-strategy」によって制御できます。

-momit-leaf-frame-pointer

リーフ関数のレジスタにスタックポインタを保存しないでください。レジスタを保存できますが、デバッグが困難になります。注:コードの非効率性を引き起こすため、-fomit-frame-pointerと同時に使用しないでください。

-m64

特に64ビット環境で実行するためのコードを生成します。32ビット環境では実行できません。x86_64[EMT64を含む]環境でのみ使用されます。

-mcmodel = small

【初期値】プログラムとそのシンボルは、2GB以下のアドレス空間に配置する必要があります。ポインタはまだ64ビットです。プログラムは静的または動的に接続できます。x86_64 [EMT64を含む]環境でのみ使用されます。

-mcmodel = kernel

カーネルは2GBのアドレス空間の外で実行されます。このオプションは、Linuxカーネルをコンパイルするときに使用する必要があります。x86_64 [EMT64を含む]環境でのみ使用されます。

-mcmodel = medium

プログラムは2GB未満のアドレス空間に配置する必要がありますが、そのシンボルは任意のアドレス空間に配置できます。プログラムは静的または動的に接続できます。注:共有ライブラリは、このオプションではコンパイルできません。x86_64 [EMT64を含む]環境でのみ使用されます。

その他の最適化オプション:

-fforce-addr

アドレスは、操作する前にレジスタにコピーする必要があります。通常、必要なアドレスは以前にレジスタにロードされるため、このオプションを使用するとコードを改善できます。

-finline-limit = n

疑似命令の数がnを超える関数の場合、コンパイラーはインライン展開を実行せず、デフォルトは600です。この値を大きくすると、コンパイル時間とコンパイルメモリの使用量が増え、生成されるバイナリファイルのボリュームも大きくなります。この値は大きすぎないようにしてください。

-fmerge-all-constants

コンパイルユニット全体のすべての定数値と配列を1つのコピーにマージしてみてください。ただし、標準のC / C ++では、変数ごとに異なる保存場所が必要であるため、このオプションを使用すると、互換性のない動作が発生する可能性があります。

-fgcse-sm

グローバル共通部分式を削除した後にストア移動を実行して、ストアをループの外に移動しようとします。gcc-3.4では、かつては「-O2」レベルのオプションでした。

-fgcse-las

グローバル共通部分式を削除した後、同じストレージ領域に格納された後の冗長なロード操作が削除されます。gcc-3.4では、かつては「-O2」レベルのオプションでした。

-floop-optimize

廃止されました(GCC-4.1は「-O1」に含まれていました)。

-floop-optimize2

元の「-floop-optimize」の代わりに、改良版のループオプティマイザーを使用してください。オプティマイザーは、さまざまなオプション(-funroll-loops、-fpeel-loops、-funswitch-loops、-ftree-loop-im)を使用して、ループ最適化のさまざまな側面を制御します。現在、この新しいバージョンのオプティマイザーはまだ開発中であり、生成されたコードの品質は以前のバージョンよりも高くありません。これは廃止され、GCC-4.1より前のバージョンにのみ存在します。

-funsafe-loop-optimizations

ループがオーバーフローせず、ループの終了条件が無限ではないと仮定します。これにより、オプティマイザ自体がこれが正しいかどうかを判断できない場合でも、比較的広い範囲でループを最適化できます。

-fsched-spec-load

いくつかのロード命令がいくつかの投機的アクションを実行できるようにします。

-ftree-loop-linear

ツリーで線形ループ変換を実行します。バッファリングのパフォーマンスを向上させ、ループをさらに最適化できます。

-fivopts

樹木に対して帰納変数の最適化を実行します。

-ftree-vectorize

木に循環ベクトル化を実行します。

-ftracer

テールコピーを実行してスーパーブロックのサイズを拡張します。これにより、関数制御フローが簡素化され、他の最適化手段をより適切に実行できるようになります。かなり効果があると言われています。

-funroll-loops

コンパイル時または実行時にループ数を判別できるループを展開するだけで、生成されるコードサイズが大きくなり、実行速度が速くなったり遅くなったりする場合があります。

-fprefetch-loop-arrays

配列の先読み命令を生成すると、巨大な配列を使用するプログラムのコード実行を高速化でき、大規模なデータベース関連ソフトウェアに適しています。具体的な効果はコードによって異なります。

-fweb

頻繁に使用されるバッファネットワークを確立して、バッファの使用率を向上させます。gcc-3.4では、かつては「-O3」レベルのオプションでした。

-ffast-math

IEEE / ANSI規格に違反して浮動小数点数の計算速度を上げることは危険なオプションです。これは、IEEE仕様に厳密に準拠しておらず、浮動小数点計算を多用するプログラムをコンパイルする場合にのみ使用することを検討してください。

-fsingle-precision-constant

浮動小数点定数を暗黙的に倍精度に変換するのではなく、単精度定数として扱います。

-fbranch-確率

-fprofile-arcsオプションを使用してプログラムをコンパイルし、それを実行して各コードブロックの実行回数を含むファイルを作成した後、このオプションを使用してプログラムを再コンパイルできます。ファイルで生成された情報は、それらを最適化するために使用されます。頻繁に発生するブランチコード。そのような情報がない場合、gccはどのブランチが頻繁に発生する可能性があるかを推測し、それを最適化します。このような最適化情報は、ソースファイルの名前と接尾辞「.da」が付いたファイルに保存されます。

-frename-registers

コード内の誤った依存関係を取り除くために、このオプションは多数のレジスターを持つマシンに効果的です。gcc-3.4では、かつては「-O3」レベルのオプションでした。

-fbranch-target-load-optimize
-fbranch-target-load-optimize2

実行シーケンスの開始と終了の前に、分岐ターゲットバッファのロードの最適化が実行されます。

-fstack-protector

キー機能のスタックに保護値を設定します。この保護値は、戻りアドレスと戻り値の前に検証されます。バッファオーバーフローが発生し、保護値が一致しなくなった場合、プログラムは終了します。プログラムが実行されるたびに、保護値はランダムであるため、リモートで推測されることはありません。

-fstack-protector-all

上記と同じですが、すべての関数のスタックに保護値を設定します。

--param max-gcse-memory = xxM

GCSE最適化の実行に使用されるメモリの最大量(xxM)が小さすぎると、最適化が不可能になります。デフォルトは50Mです。

--param max-gcse-passes = n

GCSE最適化を実行するための最大反復回数。デフォルトは1です。

アセンブラに渡されるオプション:

-Wa,options

optionsは、アセンブラーに渡すことができる1つ以上のオプションのコンマ区切りのリストです。これらはそれぞれ、コマンドラインオプションとしてアセンブラに渡すことができます。

-わ、-strip-local-absolute

出力シンボルテーブルからローカル絶対シンボルを削除します。

-Wa,-R

データセグメントとテキストセグメントを組み合わせると、データセグメントとコードセグメントの間で転送する必要がないため、アドレスの移動が短くなる可能性があります。

-Wa,--64

ワード長を64ビットに設定します。これはx86_64でのみ使用され、ELF形式のターゲットファイルでのみ有効です。さらに、「-enable-64-bit-bfd」オプションでコンパイルされたBFDサポートも必要です。

-Wa,-march=CPU

特定のCPUに応じて最適化します:pentiumiii、pentium4、prescott、nocona、core、core2; athlon、sledgehammer、opteron、k8。

CFLAGSでのみ使用可能なオプション:

-fhosted

完全な標準ライブラリを必要とするホスト環境に従ってコンパイルします。エントリはmain()関数であり、int型の戻り値を持っている必要があります。これは、カーネル外のほとんどすべてのプログラムに当てはまります。このオプションは暗黙的に-fbuiltinを設定し、-fno-freestandingと同等です。

-自立

独立した環境に従ってコンパイルすると、環境に標準ライブラリがない場合があり、main()関数は必要ありません。最も典型的な例は、オペレーティングシステムのカーネルです。このオプションは暗黙的に-fno-builtinを設定し、-fno-hostedと同等です。

CXXFLAGSでのみ使用可能なオプション:

-fno-enforce-eh-specs

C ++標準では、例外違反の必須の検査が必要ですが、このオプションを使用すると、違反検査をオフにして、生成されるコードのサイズを減らすことができます。このオプションは、「NDEBUG」マクロの定義に似ています。

-fno-rtti

'dynamic_cast'および 'typeid'を使用しない場合は、このオプションを使用して、仮想メソッドを含むクラスのランタイム表現コードの生成を禁止し、スペースを節約できます。このオプションは例外処理には無効です(rttiコードは引き続きオンデマンドで生成されます)。

-ftemplate-depth-n

テンプレートのインスタンス化の最大深度を「n」に設定します。標準を満たすプログラムは17を超えることはできず、デフォルト値は500です。

-fno-optional-diags

C ++標準で要求されていない診断メッセージを出力することは禁止されています。

-fno-threadsafe-statics

GCCは、スレッドセーフを確保するために、C ++ローカル静的変数にアクセスするコードを自動的にロックします。スレッドセーフが必要ない場合は、このオプションを使用できます。

-fvisibility-inlines-hidden

すべてのインライン関数はデフォルトで非表示になっているため、エクスポートされたシンボルテーブルのサイズが小さくなり、ファイルのサイズが小さくなるだけでなく、実行パフォーマンスも向上します。共有ライブラリをコンパイルする場合は、このオプションを使用することを強くお勧めします。-fvisibility = hiddenオプションを参照してください。

LDFLAGS

LDFLAGSは、コネクターに渡されるオプションです。これは見過ごされがちな変数です。実際、最適化への影響も非常に明白です。

-s

実行可能プログラム内のすべてのシンボルテーブルとすべての再配置情報を削除します。結果は、コマンドストリップを実行した場合と同じです。このオプションは比較的安全です。

-Wl、オプション

optionsは、1つ以上のコンマで区切られたリンカーに渡されるオプションのリストです。これらの各オプションは、コマンドラインオプションとしてリンカーに提供されます。

-Wl、-オン

n> 0の場合、出力は最適化されますが、接続動作時間は大幅に増加します。このオプションは比較的安全です。

-Wl、-exclude-libs = ALL

ライブラリ内のシンボルは自動的にエクスポートされません。つまり、ライブラリ内のシンボルはデフォルトで非表示になっています。

-Wl、-m <エミュレーション>

エミュレーション<emulation>コネクタ。現在ldで使用可能なすべてのエミュレーションは、「ld-V」コマンドを使用して取得できます。デフォルト値は、ldのコンパイル時の構成によって異なります。

-Wl、-sort-common

グローバルパブリックシンボルはサイズでソートされ、適切な出力セクションに配置されて、配置の制限によるシンボル間のギャップを防ぎます。

-Wl、-x

すべてのローカルシンボルを削除します。

-Wl、-X

すべての一時的なローカルシンボルを削除します。ほとんどのターゲットプラットフォームでは、これは名前が「L」で始まるすべてのローカルシンボルです。

-Wl、-zcomberloc

複数の再配置セクションを組み合わせて再配置し、動的シンボルをキャッシュできるようにします。

-Wl、-enable-new-dtags

新しいスタイルの「動的タグ」はELFで作成されますが、古いELFシステムでは認識されません。

-Wl、-必要に応じて

不要なシンボル参照を削除し、実際に必要な場合にのみ接続します。これにより、より効率的なコードを生成できます。

-Wl、-no-define-common

アドレスの割り当てを共通のシンボルに制限します。このオプションを使用すると、共有ライブラリから参照されるこれらの共通シンボルに、メインプログラムでのみアドレスを割り当てることができます。これにより、共有ライブラリ内の無駄なコピースペースが排除されると同時に、実行時のシンボル解決中に指定された検索パスを持つ複数の動的モジュールが存在する場合に発生する混乱を防ぐことができます。

-Wl、-hash-style = gnu

gnuスタイルのシンボリックハッシュテーブル形式を使用します。その動的リンクのパフォーマンスは、従来のsysvスタイル(デフォルト)よりも大幅に改善されていますが、生成される実行可能プログラムとライブラリは、古いGlibcおよび動的リンカーと互換性がありません。


最後に、GCCがプログラムをコンパイルする方法に影響を与えるため、最適化とは関係のない2つのシステム環境変数について説明します。次の2つは、中国人がより懸念しているものです。

LANG

コンパイラが使用する文字セットを指定します。これは、ワイド文字ファイル、文字列テキスト、およびコメントの作成に使用できます。デフォルトは英語です。[現在、日本語の「C-JIS、C-SJIS、C-EUCJP」のみがサポートされており、中国語はサポートされていません]

LC_ALL

マルチバイト文字の文字分類を指定します。これは主に、文字列の文字境界と、コンパイラが診断メッセージを発行するために使用する言語を決定するために使用されます。デフォルト設定はLANGと同じです。中国語に関連するいくつかの項目:「zh_CN.GB2312、zh_CN.GB18030、zh_CN.GBK、zh_CN.UTF-8、zh_TW.BIG5」。

https://blog.csdn.net/jc_liuworld/article/details/8267965?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=e25a6bdb-212a-4367-8e7a-132b3fb6426c&depth_1-ut pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

おすすめ

転載: blog.csdn.net/tjcwt2011/article/details/114255337