2012-02-23 28 views
12

件名を読んだ後、インテルの浮動小数点型から整数型への変換に標準のCまたはC++キャストを使用することは非常に遅いという多数の情報源からの圧倒的な証拠があります。インテルCPUは、ANSI/ISO仕様を満たすために、FPUハードウェアの丸めモードを切り替えるために必要な命令を含む多数の命令を実行する必要があります。gccでlprintがインライン展開されるようにするにはどうすればよいですか?

さまざまなドキュメントにいくつかの回避策がありますが、最もクリーンで可搬性の高いものは、C99およびC++ 0x標準に追加されたlrint()呼び出しのようです。多くの文書では、コンパイラは、最適化が有効になっているときにこれらの関数をインライン展開して、従来型のキャストや関数呼び出しよりも高速なコードにする必要があると述べています。

このインライン展開をgccオプティマイザに追加するためのgcc機能トラッキングバッグへの参照が見つかりましたが、自分のパフォーマンステストでは動作させることができませんでした。すべての私の試みは、単純なCまたはC++スタイルのキャストよりもはるかに遅くなるように、lrintのパフォーマンスを示しています。コンパイラのアセンブリ出力を調べ、コンパイルされたオブジェクトを逆アセンブルすると、常に外部lprint()またはlrintf()関数が明示的に呼び出されます。

私が扱っているgccのバージョンは4.4.3と4.6.1です。SSEを明示的に有効にするオプションを含め、32ビットと64ビットのx86ターゲットで多数のフラグの組み合わせを試しました。

は、どのように私はgccのlrintを拡張インライン、と私に高速な変換を与えることを得るのですか?

+1

実際にプロファイリングして、かなりの量のプログラムのランタイムですか? –

+2

プロファイリングでは、手書きのアセンブラマクロを使用して2〜4%の速度差を得ることができます。これは、3Dレンダリングアプリケーションのフレーム間で計算が実行されるときには有益です。 –

+1

'-fno-math-errno'を設定しましたか? '-ffast-math'の使用を検討すべきです。特定のfpセマンティクスに依存している場合、常にオプションではありません。 – Christoph

答えて

10

lrint()機能は、ドメインと範囲エラーを上げることができます。 libcがこのようなエラーを処理する可能性のある1つの方法は、errno(C99/C11セクション7.12.1を参照)を設定することです。エラー・チェックのオーバーヘッドは非常に重要であり、この特定のケースでは、オプティマイザがインライン化を決定するのに十分であると思われます。

gccフラグ-fno-math-errno(これは-ffast-mathの一部です)は、これらのチェックを無効にします。浮動小数点セマンティクス、特にNaNと無限大の標準に準拠した処理に依存しない場合は、-ffast-mathを調べることをお勧めします。

0

-finline-functionsフラグをgccに設定しましたか?

あなたは-finline-functions.

あなたはすべてのgccがインライン化するために、すべての機能を作るために言うことはできませんが、ここでhttp://gcc.gnu.org/onlinedocs/gcc/Inline.html

を参照してくださいオプションで自分の発信者にすべての「十分な単純な」機能を統合しようとするも、直接のGCCをすることができますインライン化されます。 コンパイラはヒューリスティックを使用して、関数がインライン化できるほど小さいかどうかを判断します。もう1つのことは、再帰関数もここではインラインにならないということです。

+0

私は-finline-functionsを試しましたが、コンパイラの出力には何の違いもありませんでした。 –

+0

あなたのコードでmathライブラリのlprint()を使用していてgccでコンパイルしている場合、lrint()はインライン展開されません。これは、バイナリリンクライブラリから来るからです。 lint()のコードはここにインライン化されません –

+0

このドキュメントには別途記載されています:http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html "ISO C99の機能..... lprintf、 lrintl、lrint ......は、ISO C90の厳密なモード(-ansiまたは-std = c90)以外の組み込み関数として扱われます。 さらに、これらの関数の多くは最適化されている場合もありますが、特定のケースで最適化されていない場合は、ライブラリ関数の呼び出しが行われます。私は彼らが最適化されているケースを解決することができませんでした。 –

関連する問題