Я рассматриваю возможность использования виртуального наследования в приложении реального времени. Имеет ли использование виртуального наследования влияние производительности, аналогичное действию вызова виртуальной функции? Объекты, о которых идет речь, будут созданы только при запуске, но я обеспокоен тем, будут ли отправлены все функции из иерархии через vtable или если будут только те из виртуального базового класса.Влияние виртуального наследования на производительность
ответ
Общие реализации сделают доступ к элементов данных виртуальных базовых классов использовать дополнительную косвенность.
Как отмечает Джеймс в своих комментариях, вызов функции-члена базового класса в сценарии множественного наследования потребует корректировки указателя this
, и если этот базовый класс является виртуальным, то смещение подкласса базового класса, объект в объекте производного класса зависит от динамического типа производного класса и должен быть рассчитан во время выполнения.
ли это любое видимое влияние на производительности реальных приложений зависит от многих вещей:
Do виртуального база имеет элементы данных вообще? Часто это абстрактные базовые классы, которые должны быть получены из практически, а абстрактные базы, в которых все члены данных часто являются запахами кода.
Если у вас есть виртуальные базы с членами данных, являются те, которые доступны в критическом пути? Если пользователь, нажимая на какую-либо кнопку в графическом интерфейсе, получает несколько десятков дополнительных указаний, никто не заметит.
Что бы альтернатива если виртуальные базы избежать? Мало того, что дизайн может быть хуже, также вероятно, что альтернативный дизайн также влияет на производительность. В конце концов, он должен достичь той же цели и TANSTAAFL. Затем вы торгуете одной потерей производительности для другого плюс более низкий дизайн.
Дополнительное примечание: Посмотрите на Стан Липпмана Inside the C++ Object Model, который отвечает на эти вопросы достаточно подробно.
Чтобы уточнить, только вызовы элементов/функций виртуальных базовых классов приводят к дополнительной косвенности? – Graeme
@Graeme: Я, конечно, не специалист в этой области, но я не вижу, как вызовы виртуального базового класса _functions_ приведут к потере производительности. Они либо отправляются статически ('B :: f()'), либо динамически через виртуальную таблицу производного класса, как и функции-члены не виртуальных баз. ICBWT. – sbi
@sbi: Если функция не является виртуальной, то вызываемая функция может быть выбрана статически, но указатель 'this' должен быть вычислен [или просмотрен] во время выполнения, правильно? –
Уверены ли вы, что вы имеете в виду виртуальное наследование? Если это так, то это идентично стоимости обычного вызова виртуальной функции. Поиск в виртуальной цепочке vtable следует по указанному пути.
Вы сказали, что это было при запуске. Накладные расходы на диск (от простой загрузки вашего кода в память), вероятно, потребуют на несколько порядков больше времени, чем полдюжины инструкций или около того для поиска vtable. Я был бы несколько удивлен, если бы вы могли прокомментировать это и обнаружить разницу.
Взгляните на следующее крупномасштабное экспериментальное исследование, опубликованное OOPSLA'96. Я копирую вставку записи bibtex, реферат и ссылку на бумагу. Я бы рассмотрел это наиболее полное экспериментальное исследование по этой теме на сегодняшний день.
@article{driesen1996direct,
title={{The direct cost of virtual function calls in C++}},
author={Driesen, K. and H{\\"o}lzle, U.},
journal={ACM Sigplan Notices},
volume={31},
number={10},
pages={306--323},
issn={0362-1340},
year={1996},
publisher={ACM}
}
Аннотация: Изучаются прямые затраты на виртуальной функции вызовов в программах C++, предполагая стандартную реализацию с помощью таблицы виртуальных функций. We измеряет это накладные расходы экспериментально для ряда крупных тестовых программ , используя комбинацию исполняемого контроля и моделирования процессора. Наши результаты показывают, что измеренные программные средства C++ измеряют среднюю величину в размере 5,2% от их времени и 3,7% от их инструкций в коде отправки. Для версий «все виртуальные» средние накладные расходы повышаются до 13,7% (13% от инструкций). Вариант «thunk» реализации таблицы виртуальных функций уменьшает служебные данные на медиану в 21% относительно стандартной реализации . На будущих процессорах, эти накладные расходы, вероятно, возрастет умеренно
+1 для хорошей ссылки. –
Я бы не удивился, если оптимизация компилятора сделала это исследование устаревшим. Он был опубликован в 1996 году. –
Ум. Но вопрос был о ___ виртуальном наследовании___, а не о ___ виртуальных функциях___. – sbi
Если вы не используете множественное наследование, то и нет необходимости в использовании виртуального наследования. –
@ZacHowland, если вы не используете насмешку с Google Test. (gtest) –
@ Возможно: нет «если». При использовании Google Test вы все еще используете виртуальное наследование при работе с множественным наследованием. –