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



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



pageptr[0] = pageptr[0];


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



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


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

592   3  

3 ответов:

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

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

The 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
}

Comments

    Ничего не найдено.