Как предотвратить gcc-оптимизацию некоторых операторов в C?

Вопрос:Чтобы сделать страницу грязной (включение грязного бита в записи таблицы страниц), я прикасаюсь к первым байтам страницы следующим образом: pageptr[0] = pageptr[0]; Но на практике gcc будет игнорировать утверждение путем уничтожения мертвого хранилища. Чтобы предотвратить gcc-оптимизацию, я перезаписываю оператор следующим образом: volatile int tmp; tmp = pageptr[0]; pageptr[0] = tmp; Кажется, трюк работает, но несколько

Вопрос:

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

pageptr[0] = pageptr[0];

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

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

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

Лучший ответ:

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

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

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

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

Ответ №1

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

#pragma GCC push_options #pragma GCC optimize («O0») your code #pragma GCC pop_options

отключить оптимизацию, поскольку GCC 4.4.

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

Ответ №2

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

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

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

Оцените статью
Добавить комментарий