У меня есть этот С++, который создает два производных объекта, а затем много раз вызывает вызов виртуальной функции:
Parent* d;
Child1 d1[1];
Child2 d2[1];
if(__rdtsc() & 1 != 0){
d = d1;
}
else{
d = d2;
}
for(unsigned long long i =0; i<9000000000; ++i){
sum += d->process2();
}
и он производит этот ассемблер:
for(unsigned long long i =0; i<9000000000; ++i){
000000013F4241A5 mov qword ptr [rsp+100h],0
000000013F4241B1 jmp main+2B6h (013F4241C6h)
000000013F4241B3 mov rax,qword ptr [rsp+100h]
000000013F4241BB inc rax
000000013F4241BE mov qword ptr [rsp+100h],rax
000000013F4241C6 mov rax,218711A00h
000000013F4241D0 cmp qword ptr [rsp+100h],rax
000000013F4241D8 jae main+306h (013F424216h)
sum += d->process2();
000000013F4241DA mov rax,qword ptr [rsp+0F8h]
000000013F4241E2 mov rax,qword ptr [rax]
000000013F4241E5 mov rcx,qword ptr [rsp+0F8h]
000000013F4241ED call qword ptr [rax+8]
000000013F4241F0 mov qword ptr [rsp+1D8h],rax
000000013F4241F8 mov rax,qword ptr [rsp+1D8h]
000000013F424200 mov rcx,qword ptr [sum (013F4385D8h)]
000000013F424207 add rcx,rax
000000013F42420A mov rax,rcx
000000013F42420D mov qword ptr [sum (013F4385D8h)],rax
}
Основываясь на ассемблере, может ли кто-нибудь подтвердить, что компилятор не может оптимизировать виртуальный вызов в цикле (даже если каждая итерация вызывает один и тот же производный объект), потому что компилятор не может знать, был ли выбран d1
или d2
из-за вызова только __rdtsc()
быть разрешимым во время выполнения?
(Если бы кто-нибудь мог дать мне совет, как читать ассемблер для вызова d->process2()
, я был бы очень признателен)