2013-12-07 4 views
9

Мне пришлось разработать и разработать модуль C++, который будет использоваться в среде реального времени (он будет работать на современном многоядерном ПК). Когда я его разработал, я создал C++-интерфейсы (классы с только чистыми виртуальными функциями-членами), и я использовал инъекцию зависимостей, чтобы проверить ее с помощью Google Mock Framework. Я знаю, что у этого подхода были накладные расходы на выполнение, которые были рассчитаны на статическую привязку, но проверка была важным фактором.Изменчивость производительности чистых виртуальных вызовов C++

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

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

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

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

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

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

Спасибо!

Update: Я хотел бы поставить ссылки и документы, в которых я нашел ответ:

  1. Как работает вызов виртуальной функции: Parashift C++ FAQ
  2. Technical Report on C++ Performance, стр 87: «Если статический тип объекта может быть определен во время компиляции, вызов виртуальной функции может быть не более дорогим, чем вызов не виртуальной функции-члена. Если тип должен быть динамически определен во время выполнения, служебные данные обычно будут фиксированным числом машинных инструкций (§5.3.3) для каждого вызова. "
  3. Agnes Fog's Optimizing software in C++: An optimization guide for Windows, Linux and Mac platforms, стр. 53: «Время, которое требуется для вызова функции виртуального участника, - это несколько тактовых циклов, которые требуется для вызова не виртуальной функции-члена, при условии, что оператор вызова функции всегда вызывает одну и ту же версию виртуальной функции ".
+3

«поздняя привязка имеет недетерминированную природу», звучит для меня как бессмыслица – john

+2

Существует очень мало (неконкурентных) вычислений, которые имеют недетерминированный характер. Попросите их придумать конкретный пример, иллюстрирующий, что они означают. – NPE

+1

Я согласен с @NPE - бремя доказывания должно быть им. –

ответ

13

Международный комитет по стандартизации С ++ в 2005 году опубликовал Technical Report on C++ Performance, который, как я считаю, квалифицируется как статья, так и эталонная тема.

Короткий ответ заключается в том, что промахи в кеше могут значительно повлиять на время выполнения, а при вызове виртуальной функции, как правило, консультируется с vtable.

Но на практике (в отличие от формального) накладные расходы на каждый вызов с точки зрения выполненного машинного кода составляет , фиксированный, поскольку все существующие скомпилированные реализации C++ используют vtables.Вы можете выводить классы в контент вашего сердца, не затрагивая накладные расходы. Любой вызов по-прежнему выполняет (1) поиск указателя vtable в известном месте в объекте, (2) поиск адреса функции в известном месте в vtable, (3) вызов этой функции, если компилятор не знает, что указатель функции доступен из, например. более ранний вызов, который, как ни странно, заставляет вызов идти быстрее.

+0

+1. TR действительно интересное чтение. Тот факт, что он нигде не упоминает о недетерминированности (по крайней мере, когда речь заходит о вызовах виртуальных функций), является достаточным доказательством для меня, что претензия, с которой сталкивается OP, является фиктивной. –

+0

Спасибо! Это именно то, что я искал. :) –

Смежные вопросы