我必须设计和开发一个将在实时环境中使用的C ++模块(它将在现代多核PC上运行)。当我设计它时,我创建了C ++接口(只有纯虚拟成员函数的类),我使用依赖注入,以便能够使用Google Mock Framework进行测试。我知道这种方法的运行时性能开销与静态绑定有关,但可测试性是一个重要因素。
我认为我们可以在开发过程中测量执行时间,并在集成阶段运行测试,以确定性能开销是否可以接受。
在过去的几天里,我收到批评者称这种方法不起作用,因为后期绑定具有不确定性。这种非确定性本质意味着即使我测试它并测量执行时间,之后,在生产环境中,执行时间可能更多只是因为后期绑定(因为我使用了纯虚函数)。
据我所知,这是不可能的(除了缓存未命中和类似的东西)。如果使用接口,则意味着您将有一些额外的间接层,并且编译器在某些情况下无法优化(例如内联函数),但就是这样。
所以我的问题不是性能开销,而是性能的可变性。它可以在两次执行之间变化吗?
我找不到关于此主题的任何文章或基准。找到的文章对静态和动态绑定之间的恒定性能差异进行了基准测试,但现在不再是问题了。
如果您知道任何可公开访问的文章,网页,图书,来源或任何可以提供帮助的内容,请与我分享。
谢谢!
更新 我想把链接和文件放在我找到答案的地方:
答案 0 :(得分:14)
2005年国际C ++标准化委员会发布了一个Technical Report on C++ Performance,我认为该文章既有资格也有关于此主题的基准。
简短的回答是缓存未命中会大大影响运行时间,并且在调用虚函数时,通常会查询vtable。
但是在实践中(与正式相反),就执行的机器代码而言,每次调用的开销是已修复,因为所有现有的已编译C ++实现都使用vtable。您可以在不影响呼叫开销的情况下为您的内容派生类。任何调用仍然执行(1)在对象中的已知位置查找vtable指针,(2)在vtable中的已知位置查找函数地址,(3)调用该函数,除非编译器知道函数指针可用于例如一个较早的电话,如果有的话,只是让电话更快一点。