gcc -finline-функции поведения? - PullRequest
6 голосов
/ 16 марта 2010

Я использую gcc с оптимизацией -finline-functions для релизных сборок. Чтобы бороться с раздуванием кода, потому что я работаю во встроенной системе, я хочу сказать, не включайте определенные функции. Очевидный способ сделать это - использовать атрибуты функции, т.е. attribute (noinline). Проблема в том, что это не работает, когда я включаю глобальную оптимизацию -finline-функций, которая является частью ключа -O3.

Это также связано с тем, что оно шаблонизировано, поскольку не шаблонная версия той же функции не становится встроенной, как и ожидалось.

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

Вот код:

#include <cstdlib>
#include <iostream>

using namespace std;

class Base
{
public:

    template<typename _Type_>
    static _Type_ fooT( _Type_ x, _Type_ y ) __attribute__ (( noinline ));
};

template<typename _Type_>
_Type_ Base::fooT( _Type_ x, _Type_ y )
{
    asm("");
    return x + y;
}


int main(int argc, char *argv[])
{
    int test = Base::fooT( 1, 2 );
    printf( "test = %d\n", test );

    system("PAUSE");
    return EXIT_SUCCESS;
}

Ответы [ 3 ]

4 голосов
/ 16 марта 2010

Документы для GCC noinline говорят:

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

     asm ("");

(см. Extended Asm) в вызываемую функцию, чтобы она служила особым побочным эффектом

Я думаю, чтос вами может случиться то, что, поскольку функция Base::fooT<> не имеет побочных эффектов, GCC вызывает неуказанные другие оптимизации, упомянутые выше.

1 голос
/ 22 декабря 2011

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

EDIT

В GCC> = 4.5 есть атрибут noclone, который заменяет noinline в смысле специализации функции.

1 голос
/ 21 декабря 2011

Попробуйте поставить атрибут noinline после static и перед определением, например:

   template<typename _Type_>
    static __attribute__ (( noinline )) _Type_ fooT( _Type_ x, _Type_ y );

Это сработало для меня и, похоже, работает и для других, см .: Как я могу сказать gcc не включать функцию?

По какой-то причине не получается поместить атрибут noinline после функции или поместить asm("") в тело функции, несмотря на то, что сказано в документации gcc.

...