Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Undisputed
212 / 140 / 38
Регистрация: 10.06.2014
Сообщений: 1,698
Завершенные тесты: 3
1

Мешает ли разделение кода на объявление (.h) и определение (.cpp) inline оптимизации?

22.08.2017, 16:33. Просмотров 409. Ответов 18
Метки нет (Все метки)

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

Выходит если важна производительность, то такие хедера лучше не использовать?

Насколько я понимаю использование .h файлов дают возможность ознакомиться с интерфейсом реализации в простой форме(не вникая в саму реализацию когда мы читаем код), а так же ускоряет компиляцию за счёт того что в единице трансляции отсутствует код реализации, за счёт этого конечный бинарник по идее должен быть меньше чем если бы мы включали реализацию в каждую единицу трансляции. Верны ли эти утверждения?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.08.2017, 16:33
Ответы с готовыми решениями:

Разделение кода на cpp и h файлы
Добрый день. Расскажите, пожалуйста, как разделить код на два файла cpp и файл...

Разделение программы на .h .cpp .cpp
Никак не пойму как правильно разделять программу на несколько файлов. Вот...

Inline методы класса в cpp-файле
Добрый день. Будут ли inline методы также компилироваться, если их тела...

Разделение на .cpp и .h
Здравствуйте! Прошу прощения за повтор, честно смотрела другие похожие, но все...

Разделение на h и cpp
На форуме есть темы с таким же названием, но тамошние приемы мне что-то не...

18
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
22.08.2017, 21:04 2
Ты просто смотришь на вопрос в немного вывернутой форме. При проектировании программы функции нужно распихивать по различным модулям (единицам компиляции) таким образом, чтобы горячие вызовы по возможности находились внутри одного модуля. Грамотное использование *.h упрощает этот процесс
1
Croessmah
++Ͻ
14740 / 8422 / 1597
Регистрация: 27.09.2012
Сообщений: 20,714
Записей в блоге: 2
Завершенные тесты: 1
22.08.2017, 21:12 3
Цитата Сообщение от Undisputed Посмотреть сообщение
Выходит если важна производительность, то такие хедера лучше не использовать?
На такой случай имеются предкомпилированные заголовки.
Цитата Сообщение от Undisputed Посмотреть сообщение
конечный бинарник по идее должен быть меньше
inline-функции с внешней линковкой и шаблоны сведутся
к одной реализации, остальные будут выпилены.
1
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
22.08.2017, 21:43 4
Цитата Сообщение от Croessmah Посмотреть сообщение
На такой случай имеются предкомпилированные заголовки
Они влияют только на скорость компиляции, но не на производительность кода (ТС говорит именно о ней)
1
Undisputed
212 / 140 / 38
Регистрация: 10.06.2014
Сообщений: 1,698
Завершенные тесты: 3
22.08.2017, 22:59  [ТС] 5
Evg,
Всмысле в один модуль? По смыслу это может быть некорректно... Может быть как модуль работающий с базой данных, а другой работает с сетью, ты предлагаешь все это оформить как один модуль?

Но я так и не понял как решить проблему которая связывает руки компилятору и не позволяет ему инлайнить(если конечно это утверждение верно, и такая проблема есть. Во всяком случае читал что есть...).

Первое что приходит в голову это не использовать .h
0
Убежденный
Ушел с форума
Эксперт С++
16126 / 7273 / 1181
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
23.08.2017, 11:53 6
Цитата Сообщение от Undisputed Посмотреть сообщение
Читал что когда включают хедер но не реализацию в единицу трансляции, это мешает компилятору инлайнить функции/методы ввиду того что нужного кода в этой единице трансляции нет
Для современных компиляторов это не помеха.
Не могу не вспомнить нашу старую дискуссию с Evg по этому поводу:
реализация класса в .h файле хорошо или плохо?

Цитата Сообщение от Undisputed Посмотреть сообщение
Первое что приходит в голову это не использовать .h
Я бы посоветовал в первую очередь решать архитектурные и алгоритмические вопросы, а
уже последним делом заниматься "выжиманием тактов" и т.п.
1
Renji
2114 / 1552 / 473
Регистрация: 05.06.2014
Сообщений: 4,505
23.08.2017, 12:10 7
Цитата Сообщение от Undisputed Посмотреть сообщение
Читал что когда включают хедер но не реализацию в единицу трансляции, это мешает компилятору инлайнить функции/методы ввиду того что нужного кода в этой единице трансляции нет, инлайнить нечего, и поэтому компилятор вынужден генерировать код который представляет собой именно вызов функции.
Инлайн повышает производительность за счет того, что устраняются пляски с бубном необходимые перед началом выполнения функций/методов. Но так как устранять то там особо и нечего, оправдано это только для функций на полторы строчки. Вот собственно, функции на полторы строчки в хедере и остаются. А что побольше - выносится в .cpp файл.

Отдельный пункт - разделение кода на h и cpp может порождать так называемый недостижимый код. Это когда сначала компилятор скомпилировал функцию потому что "ну она же есть в cpp, может из других cpp вызывается". А потом оказалось что нигде эта функция не вызывается, так мертвым грузом и висит. На производительность это не влияет, но вес exe увеличивает. Что, правда, не особо заметно на фоне безобразия "прилинкую мегабайт stl-библиотек, потому что мне лень распиливать один шмат заранее скомпилированного кода на десяток шматиков поменьше" (че? Безобразие? Купи терабайтный винт и гигабитный инет, нищеброд!).
1
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
23.08.2017, 12:13 8
Цитата Сообщение от Undisputed Посмотреть сообщение
Может быть как модуль работающий с базой данных, а другой работает с сетью, ты предлагаешь все это оформить как один модуль?
Нет. Я предлагаю не "оформлять в один модуль", а "оформлять в один модуль с учётом того", что какие-то фрагменты (в нашем случае inline-функции), формально не относящиеся к данному модулю, но используемые им, находятся в файле *.h другого модуля. Очевидно, что в *.h файл следует помещать то, что действительно важно с точки зрения производительности (в нашем случае inline)

Я тут всё-таки предполагаю, что ты действительно понимаешь, что такое *.h (т.е. как работает директива #include)

Цитата Сообщение от Убежденный Посмотреть сообщение
Я бы посоветовал в первую очередь решать архитектурные и алгоритмические вопросы
Правильное распихивание по модулям и хидерам - это в общем-то тоже архитектурные вопросы. Но в общем с тобой соглашусь - сначала нужно научиться просто правильно решать вопросы проектирования, а потом уже делать это же самое, но с оглядкой на производительность. Пытаться решить (в смысле учиться) оба вопроса одновременно - это слишком сложно

Не по теме:

Цитата Сообщение от Убежденный Посмотреть сообщение
Не могу не вспомнить нашу старую дискуссию с Evg по этому поводу
На форуме очень много подобных полезных споров. Временами так хочется взять такую тему, выкинуть из неё весь мусор, весь срач, весь сарказм, весь спор и оставить только материал по существу. Один раз я даже попытался это сделать и вроде бы именно по той самой теме. Потратил на это много времени и понял, что получилась фигня. Просто потому, что в споре как минимум две стороны и они освещают взгляд на вопрос каждый по своему. А после выкидывания спора остаётся "как нужно делать правильно", но при этом практически полностью теряется "почему нужно делать именно так, а не эдак". В итоге больше пользы будет при чтении оригинального спора, пусть даже и читать это трудно

2
Undisputed
212 / 140 / 38
Регистрация: 10.06.2014
Сообщений: 1,698
Завершенные тесты: 3
23.08.2017, 12:32  [ТС] 9
Убежденный,
Спасибо за совет! Ну алгоритмы и архитектура это само собой, просто хотел уточнить для себя этот момент, что бы лучше разбираться в том как это работает

Renji,
Evg,
В целом понятно, спасибо!

Ещё читал что можно перед объявлением функции в .h файле явно написать ключевое слово inline и что это поможет компилятору заинлайнить эту функцию. Но каким образом, если единица трансляции уже скомпилирована а реализация находится за её пределами?

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

И не знаешь кому верить. Наверное надо учиться понимать ассемблерные листинги, компилить, проверять на каждом компиляторе....
0
Renji
2114 / 1552 / 473
Регистрация: 05.06.2014
Сообщений: 4,505
23.08.2017, 12:41 10
Цитата Сообщение от Undisputed Посмотреть сообщение
Ещё читал что можно перед объявлением функции в .h файле явно написать ключевое слово inline и что это поможет компилятору заинлайнить эту функцию. Но каким образом, если единица трансляции уже скомпилирована а реализация находится за её пределами?
Реализация может лежать в том же h файле:
C++
1
2
3
4
5
6
7
struct Test
{
    inline void inlineFunction();
};
 
//нужно если inlineFunction использует некий класс, не определенный перед Test
inline void Test::inlineFunction(){}
0
Undisputed
212 / 140 / 38
Регистрация: 10.06.2014
Сообщений: 1,698
Завершенные тесты: 3
23.08.2017, 12:55  [ТС] 11
Renji,
Ну когда реализация находится в том же файле это вопросов не вызывает...
0
Croessmah
++Ͻ
14740 / 8422 / 1597
Регистрация: 27.09.2012
Сообщений: 20,714
Записей в блоге: 2
Завершенные тесты: 1
23.08.2017, 13:59 12
Ещё читал что можно перед объявлением функции в .h файле явно написать ключевое слово inline и что это поможет компилятору заинлайнить эту функцию.
Без inline потом получим multiple definition
для функций с внешней линковкой.
1
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
23.08.2017, 14:48 13
Цитата Сообщение от Undisputed Посмотреть сообщение
Ещё читал что можно перед объявлением функции в .h файле явно написать ключевое слово inline и что это поможет компилятору заинлайнить эту функцию. Но каким образом, если единица трансляции уже скомпилирована а реализация находится за её пределами?
http://www.cyberforum.ru/blogs/18334/blog93.html раздел 2.1
Правда вопрос я толком всё равно не понял
1
hoggy
Заблокирован
Эксперт С++
23.08.2017, 15:58 14
Цитата Сообщение от Renji Посмотреть сообщение
так мертвым грузом и висит
линкер? не, не слышал.

Добавлено через 8 минут
Цитата Сообщение от Undisputed Посмотреть сообщение
Читал что когда включают хедер но не реализацию в единицу трансляции, это мешает компилятору инлайнить функции/методы
современному компилятору никто не мешает подглядеть
что есть в спп файлах.

другое дело, если вы уже собрали статическую либу,
то оптимизировать её код при линковке с целевым приложением
он уже не будет.

Цитата Сообщение от Undisputed Посмотреть сообщение
Выходит если важна производительность, то такие хедера лучше не использовать?
нет. если важна производительность,
нужно использовать эффективные алгоритмы,
а не пытаться экономить на спичках.

инйлан компилятора - его епархия.
он сам знает что и когда нужно инлайнить.
вас это не касается.
1
Renji
2114 / 1552 / 473
Регистрация: 05.06.2014
Сообщений: 4,505
23.08.2017, 16:34 15
Цитата Сообщение от hoggy Посмотреть сообщение
линкер? не, не слышал.
Линкер работает с объектными модулями содержащими код для всего cpp разом. Вычленять оттуда код отдельных недостижимых функций он не умеет. Если быть точным, gcc с ключом -ffunction-sections все же может генерировать "умные" объектные файлы, в которых функции не перемешались в неразделимую кашу. Но по умолчанию на это забивается.
0
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
23.08.2017, 16:44 16
Цитата Сообщение от Renji Посмотреть сообщение
Если быть точным, gcc с ключом -ffunction-sections все же может генерировать "умные" объектные файлы, в которых функции не перемешались в неразделимую кашу
Но потом ещё надо производить всякие телодвижения с линкером, чтобы он удалял ненужные секции (минимальная единица, с которой работает линкер - это секция). При этом по умолчанию линкер ничего удалять не будет, там то ли какая-то опция нужна, то ли через скрипт надо удалять. В любом случае возлагать на линкер удаление ненужных функций таким способом - это в первую очередь говорит о том, что софт и/или его система сборки спроектирован коряво
0
hoggy
Заблокирован
Эксперт С++
23.08.2017, 16:50 17
Цитата Сообщение от Renji Посмотреть сообщение
Линкер работает с объектными модулями содержащими код для всего cpp разом.
для всего lib/bin
и он очень хорошо умеет вычленять весь неиспользованный стафф.
0
Croessmah
++Ͻ
14740 / 8422 / 1597
Регистрация: 27.09.2012
Сообщений: 20,714
Записей в блоге: 2
Завершенные тесты: 1
23.08.2017, 16:52 18
Evg, strip, емнип, выпилит неиспользуемые функции.
0
Evg
Эксперт CАвтор FAQ
19305 / 7160 / 533
Регистрация: 30.03.2009
Сообщений: 20,038
Записей в блоге: 30
24.08.2017, 16:47 19
Цитата Сообщение от Croessmah Посмотреть сообщение
Evg, strip, емнип, выпилит неиспользуемые функции
Нет. strip выпиливает только "ненужные" секции. "Ненужность", думается, определяется на основании того, что секция не загружается в память в момент запуска программы (например, секции с отладочной информацией)
1
24.08.2017, 16:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.08.2017, 16:47

Разделение шаблона на h и cpp и макросы
известно, что нельзя в общем случае разделить шаблон на h и cpp, конкретизация...

Разделение проекта на файлы .cpp где полностью описывается один класс
Всем привет! Бьюсь над задачей: есть несколько классов, куча объявленных...

Определение метода вне класса, как inline в многофайловом проекте
Здравствуйте! Помогите разобраться!) В общем имеется: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru