Cast-Kosten reinterpret_cast

Lesezeit: 4 Minuten

Benutzeravatar von fulmicoton
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?

Benutzeravatar von MSalters
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

Benutzeravatar von Billy ONeal
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

Benutzeravatar von user13947194
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.

1408390cookie-checkCast-Kosten reinterpret_cast

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy