2011-02-04 3 views
18

Я рассматриваю возможность использования виртуального наследования в приложении реального времени. Имеет ли использование виртуального наследования влияние производительности, аналогичное действию вызова виртуальной функции? Объекты, о которых идет речь, будут созданы только при запуске, но я обеспокоен тем, будут ли отправлены все функции из иерархии через vtable или если будут только те из виртуального базового класса.Влияние виртуального наследования на производительность

+1

Если вы не используете множественное наследование, то и нет необходимости в использовании виртуального наследования. –

+0

@ZacHowland, если вы не используете насмешку с Google Test. (gtest) –

+3

@ Возможно: нет «если». При использовании Google Test вы все еще используете виртуальное наследование при работе с множественным наследованием. –

ответ

22

Общие реализации сделают доступ к элементов данных виртуальных базовых классов использовать дополнительную косвенность.

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

ли это любое видимое влияние на производительности реальных приложений зависит от многих вещей:

  • Do виртуального база имеет элементы данных вообще? Часто это абстрактные базовые классы, которые должны быть получены из практически, а абстрактные базы, в которых все члены данных часто являются запахами кода.

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

  • Что бы альтернатива если виртуальные базы избежать? Мало того, что дизайн может быть хуже, также вероятно, что альтернативный дизайн также влияет на производительность. В конце концов, он должен достичь той же цели и TANSTAAFL. Затем вы торгуете одной потерей производительности для другого плюс более низкий дизайн.


Дополнительное примечание: Посмотрите на Стан Липпмана Inside the C++ Object Model, который отвечает на эти вопросы достаточно подробно.

+0

Чтобы уточнить, только вызовы элементов/функций виртуальных базовых классов приводят к дополнительной косвенности? – Graeme

+0

@Graeme: Я, конечно, не специалист в этой области, но я не вижу, как вызовы виртуального базового класса _functions_ приведут к потере производительности. Они либо отправляются статически ('B :: f()'), либо динамически через виртуальную таблицу производного класса, как и функции-члены не виртуальных баз. ICBWT. – sbi

+1

@sbi: Если функция не является виртуальной, то вызываемая функция может быть выбрана статически, но указатель 'this' должен быть вычислен [или просмотрен] во время выполнения, правильно? –

0

Уверены ли вы, что вы имеете в виду виртуальное наследование? Если это так, то это идентично стоимости обычного вызова виртуальной функции. Поиск в виртуальной цепочке vtable следует по указанному пути.

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

3

Взгляните на следующее крупномасштабное экспериментальное исследование, опубликованное 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% относительно стандартной реализации . На будущих процессорах, эти накладные расходы, вероятно, возрастет умеренно

http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf

+1

+1 для хорошей ссылки. –

+4

Я бы не удивился, если оптимизация компилятора сделала это исследование устаревшим. Он был опубликован в 1996 году. –

+6

Ум. Но вопрос был о ___ виртуальном наследовании___, а не о ___ виртуальных функциях___. – sbi