10

最近、数値計算でFortranがc / c ++よりも高速である主な理由は、ポインターエイリアシングがないためです。

明らかに、restrictまたは__restrict__キーワードを使用すると、ケースバイケースで、特定のメモリ要素にポインタエイリアスがないことを示すことができます。

iccコンパイラには、-fno-aliasエイリアシングが存在しないとグローバルに想定できるオプションがあるようです。gccには-fno-strict-aliasing、すべてのエイリアシング状況のサブセットにのみ適用されるがあります。

gccにオプションがありますか、または特定の最適化フラグを使用するときにエイリアシングが想定されない場合がありますか?

4

1 に答える 1

17

GCCには、-fstrict-aliasingエイリアシングの最適化をグローバルに有効にするオプションがあり、違法にエイリアシングされるものがないことを確認する必要があります。この最適化は可能で-O2あり、-O3私は信じています。

ただし、C ++には明確に定義されたエイリアシングルールがあり、標準に準拠したコードは厳密なエイリアシングと競合しません。特に、これは、別のタイプへのポインターを介して1つの変数にアクセスすることを許可されていないことを意味します。

float f;
int * p = reinterpret_cast<int*>(&f);  // uh-oh
*p = 0x3FF00000;                       // breaks strict aliasing

このルールの重要な例外は、へのポインタを介していつでも任意の変数にアクセスできることですchar。(これは、IO操作によるシリアル化に必要です。)

エイリアシング規則は、コンパイラが同じタイプのポインタが互いにエイリアスしているかどうかを知るのに役立ちません。このことを考慮:

void add(float * a, float * b, float * c) { *c = *a + *b; }

ここで、コンパイラは、またはとはc異なるメモリを指しているかどうaかを知ることができずb、注意する必要があります。これが違いを生むところだと思います。本質的には、誰もエイリアスを作成しないことをrestrict約束することによってです。float * restrict cc

于 2011-09-04T10:32:40.930 に答える