Mein Verständnis ist, dass C++ reinterpret_cast und C Pointer Cast nur eine Funktionalität zur Kompilierzeit sind und dass es überhaupt keine Leistungseinbußen gibt.
Ist das wahr?
Fulmikoton
Mein Verständnis ist, dass C++ reinterpret_cast und C Pointer Cast nur eine Funktionalität zur Kompilierzeit sind und dass es überhaupt keine Leistungseinbußen gibt.
Ist das wahr?
MSalter
Es ist eine gute Annahme, um damit zu beginnen. Der Optimierer kann jedoch darauf beschränkt sein, was er beim Vorhandensein von a annehmen kann reinterpret_cast<>
oder C-Zeigerumwandlung. Dann ist der resultierende Code langsamer, obwohl die Umwandlung selbst keine zugehörigen Anweisungen hat.
Wenn Sie beispielsweise ein int in einen Zeiger umwandeln, hat der Optimierer wahrscheinlich keine Ahnung, worauf dieser Zeiger zeigen könnte. Infolgedessen muss es wahrscheinlich davon ausgehen, dass ein Schreiben durch diesen Zeiger jede Variable ändern kann. Das schlägt weit verbreitete Optimierungen wie das Speichern von Variablen in Registern.
Ich glaube nicht, dass “normalerweise nicht” die Antwort war, die Sie auf die Frage “ist das wahr?” beabsichtigt haben.
– Rob Kennedy
26. August 2010 um 16:11 Uhr
vielen Dank für diese Antwort. Vielleicht kann man in diesem Fall mit dem Schlüsselwort register (!?) auf GCC hinweisen.
– Fulmikoton
27. August 2010 um 10:08 Uhr
Sehr unwahrscheinlich. Bei älteren Implementierungen tat der Optimierer kaum mehr, als Variablen Registern zuzuweisen. Verwenden register
würde diese Funktion ausschalten. Heutzutage sind Registerzuweisungsalgorithmen viel, viel besser. Beispielsweise können sie ein Register für mehrere Variablen wiederverwenden und eine Variable einem Register nur für einen Teil ihrer Lebensdauer zuweisen. Dadurch ist die register
Schlüsselwort für eine Variable wird effektiv ignoriert.
– MSalter
30. August 2010 um 9:18 Uhr
Bedeutet das angesichts Ihres Kommentars, dass der Optimierer den tatsächlichen Schreibvorgang sieht, eine reinterpret_cast zwischen nur Zeigertypen werden so optimiert, dass sie keine Laufzeitkosten verursachen?
– Ephemera
1. April 2013 um 2:11 Uhr
@PLPiper: Das kann einer anderen gemeinsamen Optimierung schaden. Wenn Sie durch a schreiben float*
und dann durchlesen a int*
, kann der Optimierer die beiden Anweisungen normalerweise neu anordnen. Das Schreiben kann das Lesen nicht beeinflussen, da sich die Typen unterscheiden. Aber wenn es eine vorangehende gibt reinterpret_cast
zwischen a int*
und float*
geht der Optimierer wahrscheinlich auf Nummer sicher.
– MSalter
2. April 2013 um 6:24 Uhr
Das stimmt. Keine anderen Kosten als Leistungsgewinne/-verluste für die Ausführung von Anweisungen mit der neuen Breite, die ich hinzufügen möchte, sind nur in seltenen Fällen ein Problem. Das Casting zwischen Zeigern auf jeder Plattform, von der ich je gehört habe, ist mit keinerlei Kosten und keinerlei Leistungsänderung verbunden.
Umwandlungen im C-Stil in C++ versuchen zuerst eine static_cast und führen nur dann eine reinterpret_cast durch, wenn eine statische Umwandlung nicht durchgeführt werden kann. Ein static_cast kann den Wert des Zeigers im Fall einer Mehrfachvererbung (oder beim Casting einer Schnittstelle in einen konkreten Typ) ändern, diese Offset-Berechnung kann einen zusätzlichen Maschinenbefehl beinhalten. Dies wird höchstens 1 Maschinenbefehl sein, also wirklich sehr klein.
Ja, das stimmt. Casting-Typ mit Laufzeitkosten ist dynamic_cast.
Sie haben Recht, aber denken Sie darüber nach: reinterpret_cast bedeutet vielleicht ein schlechtes Design oder dass Sie etwas auf sehr niedrigem Niveau tun.
dynamic-cast kostet Sie stattdessen etwas, da es zur Laufzeit in einer Nachschlagetabelle nachsehen muss.
dynamic_cast
ist eher verwandt static_cast
mit Laufzeitprüfung statt reinterpret_cast
. Sie können keine polymorphen Typen mit umwandeln reinterpreT_cast
.
– Billy ONeal
26. August 2010 um 13:07 Uhr
@Billy ONeal: Sie können sich aber nicht polymorph bewusst sein.
– Matt Tischler
29. August 2010 um 5:56 Uhr
Billy ONeal
reinterpret_cast
es entstehen keine laufzeitkosten.. aber man muss aufpassen, wie bei jeder nutzung reinterpret_cast
ist die Implementierung definiert. Beispielsweise ist es möglich, a umzuinterpretieren char
Array als int
array könnte dazu führen, dass die Zielarchitektur einen Interrupt auslöst, da unterschiedliche Typen möglicherweise unterschiedliche Ausrichtungsregeln haben.
Machen Sie sich zuerst richtig, dann kümmern Sie sich um die Effizienz.
dynamic_cast
ist eher verwandt static_cast
mit Laufzeitprüfung statt reinterpret_cast
. Sie können keine polymorphen Typen mit umwandeln reinterpreT_cast
.
– Billy ONeal
26. August 2010 um 13:07 Uhr
@Billy ONeal: Sie können sich aber nicht polymorph bewusst sein.
– Matt Tischler
29. August 2010 um 5:56 Uhr
Benutzer13947194
Ich habe mir meinen Assembler-Code vor und nach der Neuinterpretation des Casting-signed-char als unsigned-char angesehen. Die Anweisungen wuchsen um etwa 3 oder vier weitere Anweisungen.
int main()
{
signed char i = 0x80;
(unsigned char&)i >>= 7;
return i;
}
Ich habe in unsigned char umgewandelt, damit der Compiler die SHL-Anweisung anstelle der SAR-Anweisung verwendet, sodass die neu verschobene Bitverschiebung zer0s anstelle des vorzeichenbehafteten var i-Bitwerts wäre.
Der Compiler scheint immer noch SAR-Anweisungen zu verwenden. Aber das neu interpretierte Casting veranlasste den Compiler, weitere Anweisungen hinzuzufügen. 3 bis 4 weitere Anweisungen!
Ich war besorgt, warum meine Unicode-Funktion zum Konvertieren von UTF8 in UTF16-Strings fast dreimal langsamer war als Win32 MultiByteToWideChar(). Jetzt mache ich mir Sorgen, dass das Casting einer der Hauptfaktoren ist.
Was ironisch ist, da wir Cast für Geschwindigkeit neu interpretieren.