2015-07-13 1 views
9

Это связано с Determine cause of segfault when using -O3? В вопросе, я улавливаю segfault в определенной функции при компиляции с -O3 с использованием конкретной версии GCC. В -O3 используются инструкции векторизации (в -O2, они не используются).Как изменить уровень оптимизации одной функции?

Я хочу обернуть одну функцию на более низком уровне оптимизации. Согласно Switching off optimization for a specific function in GCC 4.2.2, я могу это сделать. Однако, следуя различным ссылкам в вопросе и ответах, я не нахожу ответа для «как именно это сделать».

Как пометить одну функцию для использования другого уровня оптимизации?


Связанные, я не хочу, чтобы переместить эту функцию в отдельный файл, а затем предоставить другой рецепт Makefile для него. Это открывает еще одну возможность червей, например, применять ее к GCC 4.9 только на некоторых платформах.

+3

Просто создайте резервную копию, что вы * действительно * не хотите использовать опцию отдельного файла, как если бы вы скомпилировали разные блоки с разными параметрами, которые вы спустили с гурулера. –

+0

Звучит как [XY-проблема] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) для меня. Если ваш код пропускает с оптимизацией, он, скорее всего, обнаруживает _undefined behaviour_. Если это не отображается без оптимизации, это на самом деле плохой знак. Вместо того, чтобы пытаться возиться с оптимизацией, вы обязательно должны искать причину. Если вы не сможете доказать, что это связано с ошибкой в ​​компиляторе, конечно. В этом случае возникает вопрос, как вы гарантируете, что эта ошибка не появится в другом месте. Здесь, используя исправленный или новый компилятор, правильный путь. – Olaf

+0

@Olaf - проблема появляется на '-O3', но нет на' -O2'. В '-O3', GCC использует инструкции SSE. Лучшее, что я могу сказать, 'vmovdqa' требует 128-битных выровненных слов, но код не гарантирует этого. Код гарантирует, что массив будет выровнен по 64 битам, когда используется этот конкретный путь кода. Код также чист с помощью Clang и дезинфицирующего средства Undefined Behavior.Я думаю, что я работаю над ошибкой компилятора. – jww

ответ

6

Это описано в https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

Вы можете изменить уровень, объявив функцию, как это:

void some_func() __attribute__ ((optimize(1))) { 
    .... 
} 

Чтобы заставить уровень оптимизации 1 для него.

+0

есть переносное решение? это портативный, чтобы говорить? –

+0

Нет, это спецификация GCC. Clang имеет более тяжелый [optnone] (http://clang.llvm.org/docs/AttributeReference.html#optnone-clang-optnone), который убивает всю оптимизацию. Но оба являются обычными расширениями. Нет стандарта для оптимизации уровня функции. – viraptor

+0

Спасибо viraptor. Я надеялся на портативное решение, так как это библиотека с кросс-платформой. Тот же набор источников используется на Android, BSD, iOS, Linux, OS X, Solaris и Windows. – jww

1

Вот как сделать это с прагмах:

#pragma GCC push_options 
#pragma GCC optimize ("-O2") 
void xorbuf(byte *buf, const byte *mask, size_t count) 
{ 
    ... 
} 
#pragma GCC pop_options 

Чтобы сделать его портативным, что-то вроде следующего.

#define GCC_OPTIMIZE_AWARE (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__) 

#if GCC_OPTIMIZE_AWARE 
# pragma GCC push_options 
# pragma GCC optimize ("-O2") 
#endif 

Он должен быть обернут, потому что с -Wall, более старой версией GCC не понимает -Wno-unknown-pragma, и они будут вызывать шумные компиляции. Старая версия будет встречена в поле, например, GCC 4.2.1 на OpenBSD.

Но, по словам Маркуса Trippelsdorf на When did 'pragma optimize' become available? из списка рассылки GCC:

Это плохая идея, в общем, потому что «Прагма НКУ оптимизируют» подразумевается только компилятор отладки помощи. Он должен не будет использоваться в производстве код.

Смежные вопросы