Как помешать gcc оптимизировать некоторые операторы в C?
Чтобы сделать страницу грязной (включив грязный бит в записи таблицы страниц), я касаюсь первых байтов страницы следующим образом:
pageptr[0] = pageptr[0];
Но на практике gcc будет игнорировать утверждение по устранению мертвого хранилища. Чтобы не допустить оптимизации gcc, я переписываю оператор следующим образом:
volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;
Кажется, трюк работает, но несколько уродливо. Я хотел бы знать, есть ли какие-либо директивы или синтаксис, который имеет тот же эффект? И я не хочу использовать -O0
флаг, так как это принесет большой штраф производительности.
3 ответа
Отключение оптимизации устраняет проблему, но в этом нет необходимости. Более безопасная альтернатива - запретить компилятору оптимизировать хранилище с помощью volatile
классификатор типов.
// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];
volatile
Спецификатор типа указывает компилятору строго соблюдать требования к хранению и загрузке памяти. Одна цель volatile
чтобы компилятор знал, что доступ к памяти имеет побочные эффекты, и, следовательно, должен быть сохранен. В этом случае у хранилища есть побочный эффект, вызывающий ошибку страницы, и вы хотите, чтобы компилятор сохранил ошибку страницы.
Таким образом, окружающий код все еще может быть оптимизирован, а ваш код переносим на другие компиляторы, которые не понимают GCC #pragma
или же __attribute__
синтаксис.
Ты можешь использовать
#pragma GCC push_options
#pragma GCC optimize ("O0")
your code
#pragma GCC pop_options
отключить оптимизацию начиная с GCC 4.4.
Смотрите документацию GCC, если вам нужно больше деталей.
Вместо использования новых прагм, вы также можете использовать __attribute__((optimize("O0")))
для ваших нужд. Это имеет преимущество, заключающееся в применении только к одной функции, а не ко всем функциям, определенным в одном файле.
Пример использования:
void __attribute__((optimize("O0"))) foo(unsigned char data) {
// unmodifiable compiler code
}