虚拟函数编译器优化C ++ [英] Virtual function compiler optimization c++
问题描述
class Base
{
public:
virtual void fnc(size_t nm)
{
// do some work here
}
void process()
{
for(size_t i = 0; i < 1000; i++)
{
fnc(i);
}
}
}
考虑到每次在循环内调用该函数都是同一个函数,c ++编译器能否并且是否将从进程功能中优化对fnc函数的调用?还是每次调用该函数都会从vtable获取函数地址?
Can and will the c++ compiler optimize calls to the fnc function from the process funtion, considering its going to be the same function every time it's invoked inside the loop ? Or is it gonna fetch the function adress from the vtable every time the function is invoked ?
推荐答案
我检查了示例godbolt.org.结果是没有,没有编译器对此进行优化.
I checked an example on godbolt.org. the result is that NO, none of the compiler optimise that.
这是测试来源:
class Base
{
public:
// made it pure virtual to decrease clutter
virtual void fnc(int nm) =0;
void process()
{
for(int i = 0; i < 1000; i++)
{
fnc(i);
}
}
};
void test(Base* b ) {
return b->process();
}
和生成的asm:
test(Base*):
push rbp ; setup function call
push rbx
mov rbp, rdi ; Base* rbp
xor ebx, ebx ; int ebx=0;
sub rsp, 8 ; advance stack ptr
.L2:
mov rax, QWORD PTR [rbp+0] ; read 8 bytes from our Base*
; rax now contains vtable ptr
mov esi, ebx ; int parameter for fnc
add ebx, 1 ; i++
mov rdi, rbp ; (Base*) this parameter for fnc
call [QWORD PTR [rax]] ; read vtable and call fnc
cmp ebx, 1000 ; back to the top of the loop
jne .L2
add rsp, 8 ; reset stack ptr and return
pop rbx
pop rbp
ret
如您所见,
它会在每次调用时读取vtable.我猜这是因为编译器无法证明您没有在函数调用内更改vtable(例如,如果您调用placement new或一些愚蠢的事情),那么从技术上讲,虚拟函数调用可能在迭代之间发生变化.
as you can see it reads the vtable on each call. I guess it's because the compiler can't prove that you don't change the vtable inside the function call (e.g. if you call placement new or something silly), so, technically, the virtual function call could change between iterations.
这篇关于虚拟函数编译器优化C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!