Gå til innhold

Diskusjon om vtable


Anbefalte innlegg

for å ikke kapre en annen tråd her helt, flytter jeg diskusjonen om vtable hit.

 

Som kjent kan kodeanalyse (optimizern) gjøre så kosten ved en virtual metode blir borte, om den klarer å se at den ikke må slå opp i vtabelen.

eks:

struct dummy
{
virtual void foo();
};
dymmy s;
s.foo(); //denne kan resolves statisk, da s er et objekt.

 

Men vtable har også en annen kost, den koster en peker i ekstra minne (pekeren til vtabelen).

 

I en annen tråd ble det stilt et interresant spørsmål av zotbar1234

 

Hvorfor må den øke? (Jeg understreker -- må (som i "absolutt alle situasjoner, selv der statisk analyse gjør det mulig å bestemme den kalte metoden")).

 

Det korte svaret er at kompileren ikke har lov til å fjerne virtual kallet fra funksjonen, da dette vil forandre ABI (application binary interface) til objektet.

 

kilde (som beskriver det ganske godt): http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=457

 

Så rule of thumb (om du trenger denne mikrooptimeringa) bør fortsatt være å fjerne "virtual" fra funksjonene dine om du ikke trenger det!

 

zotbar1234, om du har noen andre kilder, eller eksempler som motstrider dette hadde det vært veldig kult om du posta det her :)

Lenke til kommentar
Videoannonse
Annonse

struct dummy
{
virtual void foo();
};
dymmy s;
s.foo(); //denne kan resolves statisk, da s er et objekt.

 

Denne *skal* bestemmes statisk. Ikke "kan", men skal.

 

(gud, forumprogramvaren suger på quoting. But I digress...)

 

Hvorfor må den øke? (Jeg understreker -- må (som i "absolutt alle situasjoner, selv der statisk analyse gjør det mulig å bestemme den kalte metoden")).

 

Det korte svaret er at kompileren ikke har lov til å fjerne virtual kallet fra funksjonen, da dette vil forandre ABI (application binary interface) til objektet.

 

Jeg ser at artikkelen hevder det. Jeg ser *IKKE* begrunnelsen for den uttalelsen. Gitt en klasse som ikke synes i andre translation units OG programflyt som lar seg analysere statisk for å bestemme entydig den kalte metoden, hvorfor er vtable nødvendig? Standarden krever det definitivt ikke.

 

Så rule of thumb (om du trenger denne mikrooptimeringa) bør fortsatt være å fjerne "virtual" fra funksjonene dine om du ikke trenger det!

 

Tommelfingerregel er å gi blaffen i den type mikrooptimalisering (jeg synes det er fasinerende at dette overhodet er en betraktning. Jeg har f.eks. enda til gode å se noen anbefale å unngå å bruke dicts i Python fordi at den underliggende tabellen er stor nok til 8 elementer med en gang).

  • Liker 1
Lenke til kommentar

Jeg ser at artikkelen hevder det. Jeg ser *IKKE* begrunnelsen for den uttalelsen. Gitt en klasse som ikke synes i andre translation units OG programflyt som lar seg analysere statisk for å bestemme entydig den kalte metoden, hvorfor er vtable nødvendig? Standarden krever det definitivt ikke.

 

selvfølgelig nevner ikke c++ standarden vtables, dette er er opp til de som lager compilerene (sansynligvis for å gi de mer frihet). Så vidt meg bekjent brukes vtables for å oppnå polymorphism og det er muligens derfor dette er valgt. Men dette blir kun synsing fra min side. Standarden for abi (industristandarden (som bla gcc bruker)), derimot, nevner dette: http://www.codesourcery.com/public/cxx-abi/abi.html

 

A virtual table (vtable) is a table of information used to dispatch virtual functions, to access virtual base class subobjects, and to access information for runtime type identification (RTTI). Each class that has virtual member functions or virtual bases has an associated set of virtual tables. There may be multiple virtual tables for a particular class, if it is used as a base class for other classes. However, the virtual table pointers within all the objects (instances) of a particular most-derived class point to the same set of virtual tables

(highlighting gjort av meg)

 

Men dette er ikke hvordan en saklig diskusjon fungerer. Enten kommer du med et argument, eller fungerende eksempel der du motbeviser utsagned mitt, eller så holder du kjeft. Det at du mener at det ikke er slik holder ikke. Jeg kan vanskelig motbevise din holdning, ikke har jeg noe ønske om det heller. Jeg kan nevne at msvc compiler og gcc begger bruker en vtable implementasjon og følger det jeg har sagt. (dette er så vidt meg bekjent også to av de mest utbredde compilerne)

 

 

Jeg er i stor grad enig med deg at det bør/kan være mulig å unngå, men dette er ikke hvordan det fungerer i praksis.

Endret av [kami]
Lenke til kommentar

selvfølgelig nevner ikke c++ standarden vtables, dette er er opp til de som lager compilerene (sansynligvis for å gi de mer frihet) (...)

 

Nettopp.

 

Enten kommer du med et argument, eller fungerende eksempel der du motbeviser utsagned mitt (...)

 

Eksempelet har allerede blitt gitt.

 

Jeg kan nevne at msvc compiler og gcc begger bruker en vtable implementasjon og følger det jeg har sagt.

 

Det var aldri stilt i tvil. Jeg har derimot reist tvil om påstanden "om du lager en virituel funksjon vil størrelsen på klassen øke med 8". Du har ikke belegg for denne påstanden (du har, derimot, belegg for påstanden 'om du lager en virtuell funksjon, kan størrelsen på objekter av den klassen øke med størrelsen til en peker').

 

edit: ergerlig miss.

Endret av zotbar1234
Lenke til kommentar

 

 

Enten kommer du med et argument, eller fungerende eksempel der du motbeviser utsagned mitt (...)

 

Eksempelet har allerede blitt gitt.

 

Nei, nei nei. Du har sagt at du mener det ikke bør være slik, eller at det kan være en teoretisk mulighet for det. du har ikke belegg for denne påstanden, med mindre du kan støtte det opp med noe håndfast (en lik, eller kodeeksempel)

 

Jeg kan nevne at msvc compiler og gcc begger bruker en vtable implementasjon og følger det jeg har sagt.

 

Det var aldri stilt i tvil. Jeg har derimot reist tvil om påstanden "om du lager en virituel funksjon vil størrelsen på klassen øke med 8". Du har ikke belegg for denne påstanden (du har, derimot, belegg for påstanden 'om du lager en virtuell funksjon, kan størrelsen på objekter av den klassen øke med størrelsen til en peker').

 

Nei, har du en virituel funksjon vil størrelsen på klassen øke med en peker, noe industristandarden støtter meg opp på. (jamfør tidligere linker jeg har posta)

 

 

Jeg utfordrer deg fortsatt til å komme med et eksempel der det jeg sier ikke er tilfelle.

 

 

[må bare legge til at det kan ta litt tid før jeg svarer her, er på vacation'n stuff..]

Lenke til kommentar

Nei, nei nei. Du har sagt at du mener det ikke bør være slik, eller at det kan være en teoretisk mulighet for det. du har ikke belegg for denne påstanden, med mindre du kan støtte det opp med noe håndfast (en lik, eller kodeeksempel)

 

Kodeeksempelet er allerede gitt. At du ikke vil lese det, kan jeg ikke gjøre noe med.

 

Nei, har du en virituel funksjon vil størrelsen på klassen øke med en peker, noe industristandarden støtter meg opp på. (jamfør tidligere linker jeg har posta)

 

For det første, "industristandard"? Vis meg hvor i språkdefinisjonen denne "industristandarden" ilegges noe vekt.

 

For det andre, slik allerede skissert, må det ikke være slik. Språkdefinisjonen pålegger intet slikt krav, og selv om en typisk implementasjon vil antageligvis ikke bry seg om mikrooptimaliseringer (som jeg skisserte i et eksempel) og heller velge en vtable-lignende implementasjon for alt som nevner "virtual", så er det ingen grunn for at det skal være slik. Det er ingen teknisk grunn til å implementere kall av virtuelle metoder gjennom en vtable-peker, når *alle* kall kan bestemmes vha statisk analyse.

Lenke til kommentar

Kodeeksempelet er allerede gitt. At du ikke vil lese det, kan jeg ikke gjøre noe med.

beklager, men da har nok eksempelet ditt forsvinnet fra tråden og jeg beklager. kan du vennligst reposte.

 

For det første, "industristandard"? Vis meg hvor i språkdefinisjonen denne "industristandarden" ilegges noe vekt.

enten google det, eller se tidligere linker jeg har postet.

 

...Det er ingen teknisk grunn til å implementere kall av virtuelle metoder gjennom en vtable-peker, når *alle* kall kan bestemmes vha statisk analyse...

I en factory pattern der du leser objekter fra fil, kan ikke objekttypen bestemmes statisk (eller rettere sagt vil den konkludere (galt) med at alle objekter du har registrert i factorien kan lages). Derfor må du ha et dynamisk element her.

 

som jeg har nevnt:

- gi et kodeeksempel og en kompilator som gjør det du hevder, hvis ikke er dine "poeng" verdt null. (ekstrapoeng om du skriver en kompilator selv som gjør dette!)

- jeg derimot, har kommet med flere detaljerte beskrivelser på hvorfor det er slik, og linker med kilder. (eksemplene omfatter de vanligste kompilatorene)

- intil da, ikke forvent ytterligere svar, da det du sier ikke har noen praktisk verdi/nytteverdi.

Lenke til kommentar

beklager, men da har nok eksempelet ditt forsvinnet fra tråden og jeg beklager. kan du vennligst reposte.

 

Eksempelet er ikke forsvunnet. Hvis du ikke ser det, vil neppe en gjentagelse hjelpe.

 

For det første, "industristandard"? Vis meg hvor i språkdefinisjonen denne "industristandarden" ilegges noe vekt.

enten google det, eller se tidligere linker jeg har postet.

 

Jeg gjentar, hvor i språkdefinisjonen ilegges denne industristandarden noe vekt?

 

...Det er ingen teknisk grunn til å implementere kall av virtuelle metoder gjennom en vtable-peker, når *alle* kall kan bestemmes vha statisk analyse...

I en factory pattern der du leser objekter fra fil, kan ikke objekttypen bestemmes statisk (eller rettere sagt vil den konkludere (galt) med at alle objekter du har registrert i factorien kan lages). Derfor må du ha et dynamisk element her.

 

Jeg bestred aldri at det finnes situasjoner der statisk analyse ikke vil være tilstrekkelig (og således vil en typisk implementasjon bruke en teknikk som f.eks. en vtable-peker for å implementere kall på virtuelle metoder). Men det finnes (slik allerede skissert) situasjoner der statisk analyse er tilstrekkelig for å løse alle kall under kompilering, og i disse situasjonene er ikke kall av metoder gjennom vtable-peker nødvendig; noe en kompilator *kan* benytte seg av.

 

- gi et kodeeksempel og en kompilator som gjør det du hevder, hvis ikke er dine "poeng" verdt null.

 

Kodeeksempelet er gitt. Hva kompilatoren angår, gjør ikke de kompilatorne jeg har tilgang til den aktuelle optimaliseringen (hvilket er helt uten betydning for poenget, nemlig at størrelsesøkningen er ikke et krav, men heller et ofte gjort valg).

 

- jeg derimot, har kommet med flere detaljerte beskrivelser på hvorfor det er slik, og linker med kilder. (eksemplene omfatter de vanligste kompilatorene)

 

... og du har fremdeles ikke belegg for påstanden din om størrelsesøkningen ved bruken av virtuelle metoder. Har du forstått hvorfor du ikke har belegg for den?

Lenke til kommentar
  • 2 uker senere...

fra bjarne sin faq

http://www2.research.att.com/~bs/bs_faq2.html#layout-obj

 

når den typiske implementasjonen er med vtables (alle som jeg kjenner til), må det også gi grunnlag for å si at virtual legger til en pekerstørrelse på objektet ditt.

 

på denne måten kan man unngå idiotiske ting slik som en klasse som ser slik ut

class vec2d

{

float x,y;

virtual void getsomethingstupid();

}

 

som effektivt på et 64 bit system vil doble størrelsen på objektet. Noe som er kjipt for objekter det lages millioner av.

Lenke til kommentar
  • 4 uker senere...
Tommelfingerregel er å gi blaffen i den type mikrooptimalisering (jeg synes det er fasinerende at dette overhodet er en betraktning. Jeg har f.eks. enda til gode å se noen anbefale å unngå å bruke dicts i Python fordi at den underliggende tabellen er stor nok til 8 elementer med en gang).

Nå har jeg ikke lest gjennom alt her, men dette er jeg heelt enig i. Å i det heletatt diskutere å optimere noe ved å kutte ut bruk av polymorfi (annet enn å diskutere det for interessens skyld), er tullete, og hvis det liksom er nødvendig å optimere bort overheadet ved vtables, så har man sannsynligvis et design som er så grundig fucka at man like godt kan legge opp og sende hele jævla prosjektet til /dev/null.

 

Edit: Shit, denne tråden var litt gammel. Ja, ja.

 

Uansett, jeg er forøvrig enig med zootbar1234. Såvidt jeg vet så sier ikke C++ standarden spesifikt at en kompilator at alle virtuelle kall skal resolves vha en vtable. Kan det resolves statisk, så vil det selvfølgelig være å foretrekke, og hvis dette blir gjort, er ikke en vtable nødvendig. Derfor er det heller ingen garanti for at en virtuell funksjon gjør klassen større, selv om dette er tilfelle i de mest brukte implementasjonene.

 

fra bjarne sin faq

 

http://www2.research...html#layout-obj

 

når den typiske implementasjonen er med vtables (alle som jeg kjenner til), må det også gi grunnlag for å si at virtual legger til en pekerstørrelse på objektet ditt.

Det gir grunnlag for å si at i de fleste implementasjoner, så vil virtual øke størrelsen på objektet tilsvarende størrelsen av en peker. Det gir ikke grunnlag for å si at det "er slik" i C++.

Endret av Dead_Rabbit
Lenke til kommentar

 

Nettopp. Legg merke til "typically" (La oss for øyeblikket se bort fra at Stroustrup sin FAQ ikke definerer hva en implementasjon skal eller ikke skal gjøre).

 

(...) må det også gi grunnlag for å si at virtual legger til en pekerstørrelse på objektet ditt.

 

Nei, det må det ikke. Vet du forskjellen mellom "typisk" og "en implementasjon skal"?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...