gccがCのいくつかのステートメントを最適化しないようにする方法は?


107

ページをダーティにする(ページテーブルエントリのダーティビットをオンにする)ために、次のようにページの最初のバイトに触れます。

pageptr[0] = pageptr[0];

しかし実際には、gccはデッドストアの削除によってステートメントを無視します。gccによる最適化を防ぐために、ステートメントを次のように書き直します。

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

トリックはうまくいくようですが、やや醜いです。同じ効果を持つディレクティブまたは構文はありますか?また、-O0フラグを使用したくないので、パフォーマンスが大幅に低下します。


8
@Mark -O0は最適化を停止しますが、プログラムのパフォーマンスを低下させます。私はこのコードスニペットの最適化を防止したいだけです:P
ZelluX

過去に追加したいのですが、使用-O0してもデッドコードの「最適化」を防ぐことはできませんでした。たとえば、GCCがコードに効果がないことを検出した場合、それを削除するだけです。私の知る限り、これは前の段階-O0です...しかし、それは私の経験にすぎません
スムースウェア

回答:


91

最適化をオフにすると問題が解決しますが、これは不要です。より安全な代替策は、コンパイラーがvolatile型修飾子を使用してストアを最適化しないようにすることです。

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

volatile型修飾子は、メモリに格納し、負荷の程度厳密であることをコンパイラに指示します。1つの目的はvolatile、メモリアクセスには副作用があるため、保持する必要があることをコンパイラに知らせることです。この場合、ストアにはページフォールトを引き起こすという副作用があり、コンパイラーにページフォールトを保持させたいとします。

このようにして、周囲のコードを最適化でき、GCC #pragma__attribute__構文を理解しない他のコンパイラにコードを移植できます。


2
これは、最適化をオフにするよりも望ましいと思います。この方法を使用しても、他の最適化を利用できます。
Ben S

3
ディートリッヒエップのソリューションは、ARM4.1コンパイラでは動作しません。ZelluXのソリューションでさえ機能していません。ARM4.1でこれを機能させる別の方法は、ZelluXのソリューションにあります。「temp」をグローバルな揮発性変数にします
Oculus Dexter

1
それは、上記のコンパイラにとってかなり悪いことです。
Alexey Frunze

1
@Shocker:GCCは、実際のメモリアクセスを最適化せずに変数を最適化できます。これらは別の問題です。
ディートリッヒエップ2017

2
@jww:この使用法は、そのブログ投稿で説明されている内容と一致します。volatileこれは、メモリアクセスが書き込まれたとおりに発生する必要があることを意味します。言い換えれば、私たちはそれについて慎重に検討し、それが私たちがそれが何を意味するのかを意味します。
ディートリッヒエップ2018年

184

使用できます

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

GCC 4.4以降の最適化を無効にします。

詳細が必要な場合は、GCCのドキュメントを参照してください。


3
ただし、これは関数全体でのみ機能し、特定のステートメントでは機能しないことに注意してください:gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/… "この時点以降に定義される各関数は、attribute((その関数に対してoptimize( "STRING")))が指定されました。 "
Ciro Santilli郝海东冠状病六四事件法轮功

134

新しいプラグマを使用する代わりに、 __attribute__((optimize("O0")))、ニーズに合わせてます。これには、同じファイルで定義されているすべての関数ではなく、単一の関数に適用するという利点があります。

使用例:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

3
-Olevelオプションを使用していないが、個別にオンにする個別オプションを使用した場合はどうなりますか?(私の場合、コードを壊している個々の最適化オプションがどれであるかを判断できません)
user2284570 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.