2011-02-04 12 views
18

Rozważam użycie wirtualnego dziedziczenia w aplikacji czasu rzeczywistego. Czy używanie dziedziczenia wirtualnego ma wpływ na wydajność podobny do wywoływania funkcji wirtualnej? Obiekty, o których mowa, zostałyby utworzone dopiero przy uruchomieniu, ale jestem zaniepokojony, że wszystkie funkcje z hierarchii byłyby wysłane przez vtable lub gdyby były tylko te z wirtualnej klasy bazowej.Wpływ wydajności wirtualnego dziedziczenia

+1

zwiększyć ile używasz wielokrotnego dziedziczenia, tak naprawdę nie ma potrzeby używać wirtualnego dziedziczenia. –

+0

@ZacHowland, chyba że używasz szyderstwa z testem Google. (gtest) –

+3

@Amigable: Nie ma "chyba". Podczas korzystania z Testu Google nadal dziedziczysz tylko dziedzicząc dziedzicząc wiele dziedzin. –

Odpowiedz

22

Typowe implementacje umożliwiają dostęp do elementów danych wirtualnych klas bazowych za pomocą dodatkowego pola pośredniego.

Jak zauważa James w swoich komentarzach, wywołanie funkcji składowej klasy bazowej w scenariuszu wielokrotnego dziedziczenia będzie wymagać korekty wskaźnika this, a jeśli ta klasa podstawowa jest wirtualna, wówczas przesunięcie podklasy klasy podstawowej obiekt w obiekcie klasy pochodnej zależy od typu dynamicznego klasy pochodnej i będzie musiał zostać obliczony w czasie wykonywania.

Czy to ma jakikolwiek widoczny wpływ na wydajność aplikacji rzeczywistych zależy od wielu rzeczy:

  • uwagi baz wirtualne mają członkowie danych w ogóle? Często są to abstrakcyjne klasy bazowe, które muszą pochodzić z wirtualnych źródeł, a abstrakcyjne bazy, które mają dowolnych członków danych, są często zapachem kodu.

  • Zakładając masz wirtualnych baz danych z członkami są ci, obejrzano w ścieżce krytycznej? Jeśli użytkownik kliknie jakiś przycisk w GUI, otrzyma kilkadziesiąt dodatkowych pośredników, nikt tego nie zauważy.

  • Jaki byłby alternatywa jeśli wirtualne bazy unika? Nie tylko projekt może być gorszy, ale także alternatywny projekt ma wpływ na wydajność. W końcu musi osiągnąć ten sam cel i TANSTAAFL. Potem wymieniłeś jedną stratę wydajności na inną plus niższy projekt.


Dodatkowa uwaga: Zapraszamy do obejrzenia Stan Lippmann na Inside the C++ Object Model, która odpowiada na takie pytania dość dokładnie.

+0

ABY wyjaśnić, tylko połączenia z wirtualnymi klasami podstawowymi członkowie/funkcje powodują dodatkowe pośrednie? – Graeme

+0

@ Graeme: Z pewnością nie jestem ekspertem w tej dziedzinie, ale nie widzę, w jaki sposób połączenia z wirtualnymi członkami klasy podstawowej _functions_ spowodowałyby utratę wydajności. Są one wysyłane statycznie ('B :: f()') lub dynamicznie przez wirtualną tabelę klasy pochodnej, tak jak funkcje składowe nie-wirtualnych baz. ICBWT. – sbi

+1

@sbi: Jeśli funkcja nie jest wirtualna, to wywoływaną funkcję można wybrać statycznie, ale wskaźnik "this" musi zostać obliczony [lub wyświetlony] w czasie wykonywania, prawda? –

0

Czy na pewno masz na myśli dziedziczenie wirtualne? Jeśli tak, to jest to identyczne z kosztem normalnego wirtualnego wywołania funkcji. Wyszukiwanie łańcuchowe vtable następuje po określonej ścieżce.

Powiedziałeś, że to było na starcie. Napowietrzny dysk (od zwykłego załadowania kodu do pamięci) prawdopodobnie będzie wymagał o rząd wielkości więcej niż pół tuzina instrukcji dla vtable odnośników. Byłbym nieco zaskoczony, gdybyś mógł to profilować i wykryć różnicę.

3

Spójrz na poniższą dużą próbę eksperymentalną opublikowaną OOPSLA'96. Kopiuję wklejenie wpisu bibtex, streszczenie i link do artykułu. Uznałbym to za najbardziej kompleksowe badanie eksperymentalne na ten temat.

@article{driesen1996direct, 
    title={{The direct cost of virtual function calls in C++}}, 
    author={Driesen, K. and H{\\"o}lzle, U.}, 
    journal={ACM Sigplan Notices}, 
    volume={31}, 
    number={10}, 
    pages={306--323}, 
    issn={0362-1340}, 
    year={1996}, 
    publisher={ACM} 
} 

Streszczenie: Badamy kosztów bezpośrednich funkcji wirtualnego połączenia programów w C++, przy założeniu standardowego wdrażania przy użyciu tabel funkcji wirtualnych. Mierzymy to narzut eksperymentalnie dla wielu dużych programów testowych , wykorzystując kombinację wykonywalnej inspekcji i symulacji procesora . Nasze wyniki: pokazują, że zmierzone programy C++ spędzają medianę w wysokości 5,2% swojego czasu i 3,7% swoich instrukcji w kodzie wysyłki. W przypadku wersji "wszystkich wirtualnych" , mediana kosztów ogólnych wzrasta do 13,7% (13% instrukcji). Wersja "thunk" implementacji tablicy funkcji wirtualnych zmniejsza narzut przez medianę 21% względem standardowej implementacji . Na przyszłe procesory te koszty ogólne mogą umiarkowanie

http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf

+1

+1 dla miłego odniesienia. –

+4

Nie zdziwiłbym się, gdyby optymalizacje kompilacji uczyniły te badania przestarzałymi. Został opublikowany w 1996. –

+6

Um. Ale pytanie dotyczyło ___wirtualnego dziedziczenia___, a nie o ___wirtualnych funkcjach___. – sbi

Powiązane problemy