6

C / C ++コンパイラーは、-Os、-O1、および-O2を使用する場合にのみ、定数パラメーター(コンパイル時に既知)を使用して単層関数を最適化します。すべてのレイヤーを最適化するわけではありません。-O3だけがそれを行うことができます。gccはWinAVR4.3.3であり、属性「optimize」をサポートしていません。

void inner(double value)
{
    //operations using value
    //...
}

void outer(double value)
{
    //few operations using value
    //...
    inner(value);
}

int main()
{
    inner(1); //optimize
    outer(1); //only optimize by using -O3
}

以下以外の可能な解決策は何ですか?

  1. -O3ホールドプログラムまたはファイル(誤用するとサイズが大きくなります)
  2. 関数の属性optimize-O3(4.3.3はサポートしていません)
  3. マクロ(エラーが発生しやすい)

アップデート:

//inner function
static inline void _delay_us(double __us) __attribute__((always_inline));
//outer function
void f(double);
inline f1(double);
static inline f2(double);
static f3(double);

f1は最適化されていますが、警告'_delay_us'は静的ですが、静的関数の問題のために静的ではないインライン関数'f1'で使用されています。その他は最適化されていません。


解決:

static inline void outer(double) __attribute__((always_inline));

インラインが鍵です。私の外部関数はインラインには大きすぎます。属性always_inlineは、関数を強制的にインライン化します。これにより、コンパイラーは、最適化を理解しようとするよりも少ないコンパイルコストで関数を最適化できます。-O3は、最適化を実行するのに十分スマートですが、-Osは実行できません。-OSにはいくつかのコンパイラオプションが必要な場合があります。(内部関数も静的インラインであるため、キーワードstaticが必要です。)

4

4 に答える 4

3

マクロオプション(3)にいくらか似ていますが、マクロの欠点がなく、特定の関数を作成できますinline。これにより、通常、目的の定数の最適化が行われます。もちろん、これは、関連する関数を1つの場所(またはいくつかの場所)から呼び出す場合にのみ役立ちます。そうしないと、コードの膨張が問題になります。

gccには、特定のインライン関数を(コンパイラの裁量に任せるのではなく)常にインライン化するように強制する機能があることに注意してください__attribute__ ((always_inline))。他のコンパイラは通常、同様のメカニズムを備えていますが、コマンドラインスイッチやプラグマの場合もあります。

于 2011-01-31T08:48:52.050 に答える
1

少なくともGCCでは、-O フラグは他のフラグの全負荷をオンにするだけです。たとえば、 http: //gcc.gnu.org/onlinedocs/gcc/Optimize-Options.htmlを参照してください。一般的にはお勧めできませんが、興味のあるものを有効にすることもできます。

たとえばGCCの動作が、完全に異なるコンパイラが何をするかを示すものであるかどうかはわかりません-O2-O3

于 2011-01-31T08:31:25.240 に答える
1

一般的なポイントとして、コンパイラーに提供する情報を増やすと、より適切な最適化を実行できる可能性があります。

たとえば、それらが唯一の呼び出しであると仮定するinnerと、スコープを制限し、コンパイラがそれらを最適化する方法をより柔軟にできるようにouter宣言できます。static

関数の実際の内容によっては、パラメーターを宣言してconst、コードを分析しなければ変更できないことをコンパイラーにすぐに知らせることもできます。

static void inner(const double value)
{
    //operations using value
}

static void outer(const double value)
{
    //few operations using value
    //...
    inner(value);
}
于 2011-01-31T12:20:00.397 に答える
0

outerFastの定義を含む独自のcppで定義された関数''を導入し、そのファイルのみを-O3でコンパイルするのはどうですか?innerouter

ただし、それ自体に欠点があります。

于 2011-01-31T12:58:55.967 に答える