Перейти к содержанию
    

Инлайновая функция

Четкие пацаны, которым нужен четкий инлайн пишут не функции, а макросы. Ну а потом уже разбираются с этим счастьем.

В основном потому, что инлайн - нестандартное расширение.

Но дело даже не в этом. Вот не могу себе представить, где это реально может понадобиться. Вернее, могу, но это будет оч. экзотический случай. В 99% случаев это можно отдать на откуп современному компилятору. Он умеет инлайнить сам без подсказок, причём функции из разных файлов без тела функции в хедере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

использование inline ещё не говорит о том, что функция будет сто процентов инлайниться. Для принудительного инланинга необходимо использования директиву

#pragma inline = forced

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

инлайн - нестандартное расширение.

Можно пользоваться языком, у которого ключевое слово "инлайн" прописано в стандарте.

 

Но дело даже не в этом. Вот не могу себе представить, где это реально может понадобиться.

Например, какой-то макросозаменитель, вычисление которого быстрее, чем перекладывание параметров в нужном порядке по регистрам. Да, скорее всего компилятор проявит интеллект и сам заинлайнит. А может и нет. Проще подсказать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но дело даже не в этом. Вот не могу себе представить, где это реально может понадобиться.

Результат компиляции функции-макроса, часто порождает более оптимальный код, чем результат оптимизации даже хорошего компилятора - оптимизаторы пока не идеальны.

Да и иногда полезно при отладке (без оптимизации) иметь обязательный инлайнинг. А inline в си к сожалению вещь опциональная - на усмотрение компилятора. По-крайней мере в IAR.

А ещё бывает нужно в качестве аргумента передать несуществующее значение, которое внутри макроса, конкатенируясь, даст реальные переменные/константы. Такой финт с inline-функцией не провернёшь.

А ещё бывает желательно проверять валидность аргументов функции. В обычной функции (или inline) можно сделать такую проверку только с порождением кода и работающую в run-time. В макросе можно сделать проверку в build-time, не порождающую лишнего кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно пользоваться языком, у которого ключевое слово "инлайн" прописано в стандарте.
Кстати, да. Оно есть в голых Сях уже лет семь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Начиная с C++11 в каждой новой спецификации добавляются всё новые возможности выполнения кода на этапе компиляции. Это сейчас модно, а не инлайны, с которыми компиляторы уже давным-давно научились сами разбираться. Попереключайте настройки оптимизатора и посмотрите результаты компиляции. Адептам секты пресвятого инлайна смотреть результат оптимизации с ключом Size на максимуме не рекомендую , чтобы при виде сплошного антиинлайна не возникли суицидалные мысли.

 

Сейчас мэинстрим чтобы программа вообще не порождала run-time кода :) Модно написать программу на несколько страниц и получить пару ассемблерных команд. Даже соревнования проходят кто больше кода на этапе компиляции выполнит.

 

И тут очередной такой ТС с давно уже неактуальным инлайном на белом коне въезжает. Совет ТС - если у вас есть место где не проходите по скорости, а иначе зачем гнаться за инлайном, то лучше перепишите этот кусок более оптимально наблюдая за результатом компиляции. Может даже с уходом в ASM. Но надеяться на инлайн не стоит. Даже если вы директиву принудительного инлайна поставите, компилятор может её проигнорировать. Не из вредности, а из-за продвинутости оптимизатора.

 

Кстати, приёмов оптимизации в арсенале компилятора очень много, но почему-то только инлайн так волнует души неокрепших программистов :) Почему вас раскручивание циклов вообще не волнует, а? ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Модно написать программу на несколько страниц и получить пару ассемблерных команд. Даже соревнования проходят кто больше кода на этапе компиляции выполнит.

Это же легко: Евгения Онегина в комментарий скопипастить - и дело в шляпе :biggrin:

Есть ещё соревнования по созданию самых непонятным программам: тыц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему вас раскручивание циклов вообще не волнует, а? ;)

Это точно :)

Мне здесь на форуме один товарищ недавно рассказывал и пытался убеждать, что копирование через memcpy() в любом случае быстрее, чем написать это копирование простым циклом на си. Сколько я ему не намекал, что оптимизирующий компилятор может и этот цикл и даже саму memcpy(!) раскрутить в несколько ассемблерных инструкций (в зависимости от размера пересылки, выравниваний и известности параметров пересылки на этапе компиляции), а может и то и другое заменить просто оптимальным циклом с копированием внутри - так и не убедил его. Он только обиделся. Он приводил в доказательство какие-то частные случаи, в определённых созданных им условиях.

Так он и не понял, что при включении максимальной оптимизации и чем лучше и продвинутее компилятор, тем результат будет больше зависеть от реализуемого действия (алгоритма), а не от способа его реализации (цикл-ли, инлайн или даже memcpy).

Так и ТС здесь - уверен что что-то зависит от того, с inline он напишет функцию или без. ;)

Так что как я неоднократно убеждался - понимание принципов работы оптимизаторов ускользает от основной массы программистов, сколько не описывай это в мануалах. Ну и в результирующий ассемблерный код тоже как видно мало кто смотрит и понимает его. Иначе бы даже без мануалов всё было понятно.

 

PS: Кстати - вдогонку, в тему: Иногда возникает желание сказать компилятору (IAR в частности), чтобы он не inline-ил функцию. Так это сделать посложнее чем сказать inline.

А вот сделать функцию жёстко "не inline" вне зависимости от работы оптимизатора - это имхо гораздо полезнее чем сделать её inline.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне здесь на форуме один товарищ недавно рассказывал и пытался убеждать, что копирование через memcpy() в любом случае быстрее, чем написать это копирование простым циклом на си. Сколько я ему не намекал, что оптимизирующий компилятор может и этот цикл и даже саму memcpy(!) раскрутить в несколько ассемблерных инструкций (в зависимости от размера пересылки, выравниваний и известности параметров пересылки на этапе компиляции), а может и то и другое заменить просто оптимальным циклом с копированием внутри - так и не убедил его. Он только обиделся. Он приводил в доказательство какие-то частные случаи, в определённых созданных им условиях.

Был случай, когда хотелось, чтобы memcpy был маленький и медленный. Скорость не нужна, а байтов жалко. Библиотечный memcpy шибко умный, видимо. Ускоренный настолько, что весит сотни байт :-( Хоть заменяй своим.

 

PS: Кстати - вдогонку, в тему: Иногда возникает желание сказать компилятору (IAR в частности), чтобы он не inline-ил функцию. Так это сделать посложнее чем сказать inline.

А вот сделать функцию жёстко "не inline" вне зависимости от работы оптимизатора - это имхо гораздо полезнее чем сделать её inline.

Очевидно же: взять адрес функции, загнать его в указатель volatile, не? И вызывать через этот указатель для верности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Был случай, когда хотелось, чтобы memcpy был маленький и медленный. Скорость не нужна, а байтов жалко. Библиотечный memcpy шибко умный, видимо. Ускоренный настолько, что весит сотни байт :-( Хоть заменяй своим.

Когда хочется иметь определённый ассемблерный результат, вне зависимости от умности компилятора, то есть только один надёжный выход - ассемблер. И не нужно его бояться.

 

Очевидно же: взять адрес функции, загнать его в указатель volatile, не? И вызывать через этот указатель для верности.

Не уверен что это прокатит с любым компилятором. Да, указатель он создаст, и пожалуй даже поставит команду LDR Rx, указатель. Но кто дальше ему мешает просто вставить код функции? Ведь все условия volatile указателя он уже выполнил: создал его, и чтение его выполнил.

 

PS: Про #pragma inline=never знаю и его сейчас и использую в IAR. Но это компиляторо-зависимо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А в IAR разве нет атрибутов наподобие gcc и keil?

У меня написан compiler.h в котором все нюансы компиляторов запрятаны. Типа

#if defined(__GNUC__)
#      define __is_always_inline   __inline__ __attribute__((__always_inline__))
#endif

А пользовательский код никаких специфических вещей компиляторов не использует - только свою прослойку.

static __is_always_inline void foo(void)
{
    // do something
}

ИМХО прагмы в коде последнее дело...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А в IAR разве нет атрибутов наподобие gcc и keil?

Атрибутов не знаю, знаю только прагмы. И тогда Ваш compiler.h - неверный.

 

ИМХО прагмы в коде последнее дело...

Согласен. Но я не знаю другого способа явно указать IAR-у - инлайнить или нет. :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но кто дальше ему мешает просто вставить код функции?

Как кто? Вызов функции по указателю volatile. Он же не знает, что там в этом указателе (он же volatile!), поэтому именно вызовет функцию по указателю без всяких инлайнов. И заметьте, это чистый Си, без всяких прагм и атрибутов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но я не знаю другого способа явно указать IAR-у - инлайнить или нет. :(

Не знаю с какой версии, но

In extended language mode, the IAR C/C++ Compiler also supports a limited selection

of GCC-style attributes. Use the __attribute__ ((attribute-list)) syntax for

these attributes.

The following attributes are supported in part or in whole. For more information, see the

GCC documentation.

● alias

● aligned

● always_inline

● cmse_nonsecure_call

● cmse_nonsecure_entry

● constructor

● deprecated

● noinline

● noreturn

● packed

● pcs (for IAR type attributes used on functions)

● section

● target (for IAR object attributes used on functions)

● transparent_union

● unused

● used

● volatile

● weak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Немного погуглив нашёл _Pragma(...)

#ifdef IAR
        #define NO_OPT _Pragma ("optimize=none")
#endif

NO_OPT void some_func(void)
{
…
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...