![]() |
1
28
虚拟函数非常有效。假设32位指针,内存布局约为:
classptr指向通常在堆上的内存,偶尔在堆栈上,并以指向该类vtable的四字节指针开始。但是需要记住的重要一点是vtable本身并没有分配内存。它是一个静态资源,同一类类型的所有对象都将指向其vtable数组的完全相同的内存位置。调用不同的实例不会将不同的内存位置拉入二级缓存。 example from msdn 显示具有虚拟func1、func2和func3的类A的vtable。不超过12个字节。不同类的vtables很有可能在编译库中物理上相邻(您需要验证这一点,这是您特别关心的),这可以从微观上提高缓存效率。
在本例中,堆栈帧基指针ebp具有变量
如果此函数调用不是虚拟的,则不需要mov eax和mov edx,但性能上的差异将非常小。 |
![]() |
2
11
draft Technical Report on C++ Performance 完全用于虚拟函数的开销。 |
![]() |
3
3
您是否实际分析并找到了需要优化的位置和内容?
|
![]() |
4
3
我能想到的唯一优化是Java的JIT编译器。如果我理解正确,它会在代码运行时监视调用,如果大多数调用只转到特定的实现,它会在类正确时插入条件跳转到实现。这样,大多数情况下,没有vtable查找。当然,对于通过不同课程的罕见情况,vtable仍然使用。
|
![]() |
5
3
虚拟函数往往是查找和间接函数调用。在某些平台上,这很快。在其他情况下,例如,控制台中使用的一种流行的PPC体系结构,这并没有那么快。 优化通常围绕在调用堆栈的更高层表达可变性,这样您就不需要在热点中多次调用虚拟函数。 |
![]() |
6
2
您可以在运行时使用虚拟函数实现polymorfism,在编译时使用模板实现polymorfism。可以用模板替换虚拟函数。有关更多信息,请参阅本文- http://www.codeproject.com/KB/cpp/SimulationofVirtualFunc.aspx |
![]() |
7
2
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 维基百科上的解释很清楚,也许是这样 能够 如果你真的下定决心 虚拟方法调用是性能瓶颈的根源。 |
![]() |
8
2
正如其他答案所述,虚拟函数调用的实际开销相当小。它可能会在一个被称为每秒数百万次的紧密循环中产生影响,但很少有什么大不了的。
当然,这也取决于CPU架构。在某些情况下,它可能变得相当昂贵。
但首先,确保你有问题。代码是否真的太慢而无法接受? 其次,通过探查器找出是什么使它变慢。 第三,修复它。 |
![]() |
9
2
你想知道的是:
如果虚拟函数调用过程中花费的时间很长,比如说20%,那么平均五分之一的示例将在反汇编窗口的调用堆栈底部显示跟随虚拟函数指针的指令。 如果你没有看到,这不是问题。 在这个过程中,您可能会看到调用堆栈上更高的其他东西,这些东西实际上是不需要的,并且可以为您节省大量时间。 |
![]() |
10
2
静态多态性,正如一些用户在这里回答的那样。例如,WTL使用这种方法。有关WTL实现的详细说明,请参见 http://www.codeproject.com/KB/wtl/wtl4mfc1.aspx#atltemplates |
![]() |
11
2
在某些情况下,可以做一些事情来防止该功能的浪费,即声明函数inline virtual。
当您在代码的某一点上确定要调用的对象的类型时,您可以进行内联调用,以避免多态系统,并通过编译器启用内联。
在本例中,调用
|
![]() |
12
1
缓存通常仅在处理以下大型数据结构时才会出现问题:
Vtables之类的东西通常不会成为性能/缓存/内存问题;通常,每个对象类型只有一个Vtable,并且对象包含指向Vtable的指针,而不是Vtable本身。所以,除非你有几千种类型的对象,否则我不认为Vtables会破坏你的缓存。 1) 顺便说一句,这就是为什么像memcpy这样的函数使用缓存绕过像movnt(dq | q)这样的流式指令来进行超大(数兆字节)数据输入的原因。 |
![]() |
13
1
|
![]() |
14
1
使用现代的、前瞻性的多个调度CPU,虚拟函数的开销很可能为零。娜达。拉链 |
![]() |
15
0
如果 人工智能 应用程序不需要大量的数字运算,我不会担心虚拟函数的性能缺点。只有当它们出现在重复评估的复杂计算中时,性能才会受到轻微的影响。我认为您也不能强制虚拟表留在二级缓存中。 虚拟函数有两种优化方法,
|
![]() |
AstralHex · 矩阵乘法代码工作不正常 3 月前 |
![]() |
Fishie · 作为类成员的智能指针是否仍然自动释放?[关闭] 3 月前 |
![]() |
Die4Toast · 递归调用成员箭头运算符-> 3 月前 |
![]() |
Anka Hanım · 关于结构和动态数组地址的问题 4 月前 |