Как помешать gcc оптимизировать некоторые операторы в C? - PullRequest
94 голосов
/ 08 февраля 2010

Чтобы сделать страницу грязной (включив грязный бит в записи таблицы страниц), я касаюсь первых байтов страницы следующим образом:

pageptr[0] = pageptr[0];

Но на практике gcc будет игнорировать утверждение при удалении мертвого хранилища. Чтобы не допустить оптимизации gcc, я переписываю оператор следующим образом:

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

Кажется, трюк работает, но несколько уродливо. Я хотел бы знать, есть ли какие-либо директивы или синтаксис, который имеет тот же эффект? И я не хочу использовать флаг -O0, так как это также приведет к значительному снижению производительности.

Ответы [ 3 ]

161 голосов
/ 08 февраля 2010

Вы можете использовать

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

your code

#pragma GCC pop_options

для отключения оптимизаций начиная с GCC 4.4.

См. Документацию GCC, если вам нужна дополнительная информация.

118 голосов
/ 28 января 2012

Вместо использования новых прагм, вы также можете использовать __attribute__((optimize("O0"))) для своих нужд. Преимущество этого заключается в применении только к одной функции, а не ко всем функциям, определенным в одном файле.

Пример использования:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}
79 голосов
/ 08 февраля 2010

Отключение оптимизации устраняет проблему, но в этом нет необходимости. Более безопасная альтернатива - запретить компилятору оптимизировать хранилище с помощью спецификатора типа volatile.

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

Спецификатор типа volatile указывает компилятору строго соблюдать требования к хранению и загрузке памяти. Одна из целей volatile - дать компилятору понять, что доступ к памяти имеет побочные эффекты и поэтому должен быть сохранен. В этом случае у хранилища есть побочный эффект, вызывающий ошибку страницы, и вы хотите, чтобы компилятор сохранил ошибку страницы.

Таким образом, окружающий код все еще может быть оптимизирован, а ваш код переносим на другие компиляторы, которые не понимают синтаксис GCC #pragma или __attribute__.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...