Дорогие форумчане, не инлайнит
Знаю мнение, что компилятор сам определяет что инлайнить, что нет. Близко с inline'ами не работал. Вот сейчас решил попробовать.
Казалось бы, сверх малые функции должны быть заинлайнены без проблем. Мой небольшой опыт в понимание ассемблера говорит мне о том, что нет инлайна в итоге. Есть call этих функций.
https://godbolt.org/z/vbdd1aKz4
#include <iostream>
using namespace std;
int get_limit() { return 5; }
void do_some_logic() { }
struct attempts_checker {
int limit_;
int attempts_ = 0;
inline attempts_checker(int limit) : limit_(limit)
{}
inline void operator++() {
++attempts_;
}
inline bool exceeded() {
return attempts_ < limit_;
}
};
inline bool are_exceeded(int attempts, int limit) {
return attempts >= limit;
}
int main()
{
// 1. variables
int attempt = 0;
int limit = get_limit();
attempt++;
if(attempt < limit)
do_some_logic();
// 2. struct
attempts_checker checker(get_limit());
++checker;
if(checker.exceeded())
do_some_logic();
// 3. function
int attempt_ = 0;
int limit_ = get_limit();
attempt_++;
are_exceeded(limit_, attempt_);
return 0;
}
Суть такая, что в участке где используется
attempt и
attempt_limit происходят эти проверки
if(attempt < limit) после инкремента attempt.
Поэтому я хотел сделать код чуть красивее/легче инкапсулировав эти переменные в объект. И дергать функцию
exceeded() у объекта.
В классе даже
operator++ написал не каноничный, чтобы не возвращать *this. Как надеялся, код всё-таки заинлайнился. Но нет. Везде эти ассемблерные call.
Сделал для сравнения ещё функцию
are_exceeded(...). И она не инлайнится.
Помогите, разобраться, пожалуйста.
Здравствуйте, avovana, Вы писали:
a> Помогите, разобраться, пожалуйста.
А
-O3 где?!
Здравствуйте, avovana, Вы писали:
A>Дорогие форумчане, не инлайнит
У GCC по умолчанию оптимизация не включается. Добавь хотя бы -Og, уже увидишь совсем другой вывод — точнее, оно весь main() свернуло в return 0, потому что результаты ты никуда не публикуешь

Уже на -Og какой-то инлайнинг включается, на -O больше, на -O2 совсем много.
Очень не рекомендую -O3, как посоветовали рядом, без опыта работы с этим уровнем, иногда лезут странные эффекты. Да и -O2 надо уже дозированно применять. А вот -O вполне пригоден для проверки таких вещей.
У Clang похоже, хотя он уже на -O очень агрессивен.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, avovana, Вы писали:
A>>Дорогие форумчане, не инлайнит
N>У GCC по умолчанию оптимизация не включается. Добавь хотя бы -Og, уже увидишь совсем другой вывод — точнее, оно весь main() свернуло в return 0, потому что результаты ты никуда не публикуешь
N>Уже на -Og какой-то инлайнинг включается, на -O больше, на -O2 совсем много.
N>Очень не рекомендую -O3, как посоветовали рядом, без опыта работы с этим уровнем, иногда лезут странные эффекты. Да и -O2 надо уже дозированно применять. А вот -O вполне пригоден для проверки таких вещей.
N>У Clang похоже, хотя он уже на -O очень агрессивен.
Попробовал, спасибо. Жаль, что уже нет соответствия строчки кода -> ассемблер.
Как я увидел, спокойно могу этот объект применять. Будет тоже самое. -O2 сносит разницу.
Здравствуйте, avovana, Вы писали:
A>Попробовал, спасибо. Жаль, что уже нет соответствия строчки кода -> ассемблер.
На -Og ещё неплохо сохраняется.
В Linux kernel ещё есть вкусная подсказка
ifdef CONFIG_READABLE_ASM
# Disable optimizations that make assembler listings hard to read.
# reorder blocks reorders the control in the function
# ipa clone creates specialized cloned functions
# partial inlining inlines only parts of functions
KBUILD_CFLAGS += -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining
endif
можно эти добавить и ещё поиграться чтобы улучшить соответствие.
A>Как я увидел, спокойно могу этот объект применять. Будет тоже самое. -O2 сносит разницу.
Не понял с чем разница, но ок