Wie teuer ist virtual?
-
Guten Tag.
Ich frage mich, ob es akzeptabel ist trotz dem Streben nach größtmöglicher Performance beinahe exzessiv Polymorphie auszunutzen.
Konkret handelt es sich um ein Framework welches bereits schnell ist, aber
es soll hoch performant werden und dennoch
möglichst flexibel
Der letze Grund bewegt mich und mein kleines Team viel "Virtualität"
auszunutzen und wir sind bereit das mit minimalen Geschwindigkeitseinbußen zu bezahlen.
Könnt ihr das anraten?
Ich bedanke mich für jede qualifizierte Hilfestellung!
-
Nachzulesen in "Effective C++" oder "More Effective C++", keine Ahnung mehr in welchem von beiden.
edit: Im letzteren z.B. in 4.9: Verstehe die Kosten virtueller Funktionen ...
Im Allgemeinen sollte man die beiden Buecher sowieso verinnerlicht haben.

-
exzessiv
Nein!
exzessiv ist bei jedem Sprachmittel falsch. virtual fällt bei großen Funktionen nicht ins Gewicht, bei kleineren Funktionen wirds aber nervig, weil der Compiler dann die vielen kleinen aber nützliche optimierungen nicht durchführen kann.
Flexibilität kann man auch durch Templates erreichen.
-
Dass virtual viel "teurer" sei als non-virtual, ist Quatsch. Der Unterschied ist längst nicht so groß, wie es das im Fall inline gegen non-inline sein kann.
Siehe C++ Performance
Gruß,
SP
-
Was wäre denn die Alternative? Ein switch-case-Konstrukt? Das virtual ist doch nur ein Sprung in einer Tabelle, kein Nachteil ggü. einem selber gebastleten Typ-Entscheider. Benutze virtual dann, wenn du es brauchst. Wenn du dir darüber sorgen machst, mach kein C++ sondern C...
-
Pfreak schrieb:
Konkret handelt es sich um ein Framework welches bereits schnell ist, aber
es soll hoch performant werden und dennoch
möglichst flexibelAchwasdunichtsagst.
Das nennst du konkret? Das nenne ich Gefasel, ohne einen Fetzen Information.Der letze Grund bewegt mich und mein kleines Team viel "Virtualität"
auszunutzen und wir sind bereit das mit minimalen Geschwindigkeitseinbußen zu bezahlen.Weitergefaselt.
Könnt ihr das anraten?
Ich bedanke mich für jede qualifizierte Hilfestellung!Ich würde anraten "qualifizierte" Fragen zu stellen.
-
hihihi. Unser hustebaer!

Nunja ... ein konkretes Beispiel fände ich nun auch nicht schlecht.
-
Virtual ist bei Mehrfachvererbung teurer als bei bei Einfachvererbung.
-
knivil schrieb:
Virtual ist bei Mehrfachvererbung teurer als bei bei Einfachvererbung.
Sicher? Ich bin mir nämlich fast sicher dass du da was verwechselst... (virtuelle Vererbung vs. Mehrfachvererbung).
-
hustbaer schrieb:
knivil schrieb:
Virtual ist bei Mehrfachvererbung teurer als bei bei Einfachvererbung.
Sicher? Ich bin mir nämlich fast sicher dass du da was verwechselst... (virtuelle Vererbung vs. Mehrfachvererbung).
Bei Mehrfachvererbung muß beim Aufruf virtueller Funktionen üblicherweise der this-Pointer angepaßt werden; die meisten Compiler behelfen sich hierfür mit Thunks. (Ob das freilich relevante Mehrkosten sind, sei dahingestellt.)
-
Pfreak schrieb:
Guten Tag.
Ich frage mich, ob es akzeptabel ist trotz dem Streben nach größtmöglicher Performance beinahe exzessiv Polymorphie auszunutzen.
Konkret handelt es sich um ein Framework welches bereits schnell ist, aber
es soll hoch performant werden und dennoch
möglichst flexibel
Der letze Grund bewegt mich und mein kleines Team viel "Virtualität"
auszunutzen und wir sind bereit das mit minimalen Geschwindigkeitseinbußen zu bezahlen.
Könnt ihr das anraten?
Ich bedanke mich für jede qualifizierte Hilfestellung!Du kannst (in der Regel) nicht alles haben, maximale Performanz und maximale Flexibilität. Wenn es ein Framework ist, sollen andere es verwenden, was häufig ja auch bedeutet, dass man ableiten möchte oder muss. Aus meiner Sicht ist dies oft wichtiger als Performanz. In Frameworks mache ich darum oft alle Methoden (außer private natürlich) virtual. Solche Klassen sollen ableitungsfreundlich sein!
Ich würde sagen, finde heraus, ob Performanz wirklich ein Thema ist (meist ist es das nämlich nicht), zahle an den notwendigen Stellen und legen ansonsten eher Wert auf Flexibiliät.
Stefan.
-
Wenn du sehr viele verschiedene Objekte hast mit sehr vielen virtuellen Methoden, dann sind die Sprungtabellen für die virtuellen Methoden für alle diese Klassen zusammen recht groß und wenn diese recht groß sind, aber häufig verwendet werden bleiben sie im Cache was dazu führen kann, dass diese Sprungtabellen und deine Daten (auf diese du auch ständig zugreifst) sich gegenseitig aus dem Cache verdrängen (natürlich nur, wenn nicht genug Platz vorhanden ist).
Natürlich befindet sich auch der Code von häufig aufgerufenen und den zuletzt aufgerufenen Funktionen dort.Aber da hilft nur eines: profilen. Und selbst dann muss man sich noch überlegen wieviel Cache man sich mindestens zugestehen will. Nicht jede CPU hat 6MB L2 Cache, wie die (besseren) Core 2s.
-
Kenner der Hardware schrieb:
Wenn du sehr viele verschiedene Objekte hast mit sehr vielen virtuellen Methoden, dann sind die Sprungtabellen für die virtuellen Methoden für alle diese Klassen zusammen recht groß und wenn diese recht groß sind, aber häufig verwendet werden bleiben sie im Cache was dazu führen kann, dass diese Sprungtabellen und deine Daten (auf diese du auch ständig zugreifst) sich gegenseitig aus dem Cache verdrängen (natürlich nur, wenn nicht genug Platz vorhanden ist).
Natürlich befindet sich auch der Code von häufig aufgerufenen und den zuletzt aufgerufenen Funktionen dort.Aber da hilft nur eines: profilen. Und selbst dann muss man sich noch überlegen wieviel Cache man sich mindestens zugestehen will. Nicht jede CPU hat 6MB L2 Cache, wie die (besseren) Core 2s.
Ich finde nicht, dass man sich bei Design-Entscheidungen auf diese niedrige Ebene hinunter begeben sollte. Erstens, weil's nicht unbedingt stimmt: Wie virtuelle Methoden letztlich "aufgelöst" werden, ist ein Implementierungs-Detail und hängt von tausend Umständen ab. Zweitens, weil sich Hardware ständig ändert: Was heute ein großer Cache ist, kann in ein paar Monaten winzig sein.
Es ist sinnlos, sich beim Design eines Frameworks (oder auch eines einfachen Programms) über solche Dinge den Kopf zu zerbrechen.
Stefan.