![]() |
Codeoptimierung lieber abschalten
In der Hilfe zu Delphi findet man zur Optimierung die folgenden Aussagen:
Zitat:
Das Bemerkenswerte daran: Das trat jetzt gerade nicht in einem Fall auf, in dem Timing-Geschichten oder so etwas $DINGE beeinflussen könnten, nicht um Threads, nicht um irgendwelche eingebundenen Bibliotheken, die möglicherweise sehr krude programmiert wurden. Sondern um simple String-Bearbeitung mit den Delphi-Standard-Units. Von daher meine Empfehlung: Die Codeoptimierung sollte immer deaktiviert sein. |
AW: Codeoptimierung lieber abschalten
hm. Kann ich in der Pauschalität nicht bestätigen. Man mag dem Delphi-Compiler einiges vorwerfen können, doch die klassischen String-Operationen hat er definitiv gut im Griff.
Kannst Du dies auf ein handhabbares Beispiel reduzieren? |
AW: Codeoptimierung lieber abschalten
Zitat:
Ich vermute, der Fehler wurde innerhalb einer bestehenden Anwendung beobachtet, die möglicherweise bereits Fehler enthält, die zu einem Seiteneffekt geführt haben. Das ist in der Praxis leicht möglich, wenn z.B. Speicherkorruption ausgelöst wird, oder Speichermangel besteht. |
AW: Codeoptimierung lieber abschalten
FUD.
Sherlock |
AW: Codeoptimierung lieber abschalten
Ja, es kann natürlich sein, dass die Optimierung irgendwo einen Bug hat
und dann doch dadurch etwas kapput geht. "vorübergehend" kann man dann die Optimierung global oder besser nur lokal abschalten und wendet sich dann dann an den Support -> ![]() Aber auch kann es ein Bug in Funktionen von Delphi sein, also RTL, VCL, usw. (wäre nicht das erste Mal), wo man dann eben auf andere Funktionen ausweichen könnte. So lange es keinen halbwegs reproduzierbaren Testfall gibt, oder jemand überhaupt erstmal verrät, was eigentlich das Problem sein soll, kann aber schlecht irgendjemand eine Lösung finden. Zitat:
NEIN |
AW: Codeoptimierung lieber abschalten
Ich hatte das definitiv schon mehrfach, dass ich für einige Codezeilen die Optimierung ausschalten musste, weil der Compiler sonst fehlerhaften Code erzeugte. Das war reproduzierbar:
Solche Fälle hatte ich bei Delphi 2006, 2007, XE2 und Delphi 10.2, wenn auch nicht notwendigerweise an denselben Code-Stellen. Da ich Delphi 11 so gut wie nicht benutze, kann ich dazu nichts sagen. Ich habe keine Bugreports geschrieben, da es sich nie um die aktuelle Delphi-Version handelte und meiner Erfahrung nach Bugreports für ältere Versionen einfach ignoriert werden. Keiner prüft, ob der Fehler bei der aktuellen Version vielleicht auch noch auftritt. |
AW: Codeoptimierung lieber abschalten
Zitat:
|
AW: Codeoptimierung lieber abschalten
Zitat:
Ein paarmal waren es aber echte Compilerprobleme, die aber alle schnell behoben wurden, und auch alle die jeweils aktuelle Version betrafen. |
AW: Codeoptimierung lieber abschalten
Zitat:
Bei Schleifen ist es schön, dass es nun die Inlinevariablen gibt. Da kann man danach garnicht erst auf soeine blöde Idee kommen.
Delphi-Quellcode:
Jo, auch zwinschen Platformen und sogar zwischen Win32 und Win64 gibt es solche Problemchen.
for var i: Byte := 0 to 123 do
for var i := 0 to 123 do for var S in SL do ... Wo z.B. Result plötzlich "null" ist, wenn man es vergessen hat, oder eben wo Variablen unterschiedliche "Initial"-Werte haben, jenachdem ob sie auf dem Stack oder in den Registern liegen, bzw. ob sie über die ganze Funktion oder nur den genutzen Zeitraum vorhanden sind usw. Ebenso, wie bei gemangten Results, wäre es bei Schleifen gut, wenn nach dem Ende der Compiler "vergessen" würde, dass die Variable "eigentlich" schon initialisiert ist. Dann gäbe es bei nachfolgenden Lesezugriffen auch eine entsprechende Warnung. |
AW: Codeoptimierung lieber abschalten
Zitat:
Ich finde übrigens
Delphi-Quellcode:
praktisch.
{$IFDEF DEBUG}
{$OPTIMIZATION OFF} {$ENDIF} |
AW: Codeoptimierung lieber abschalten
Zitat:
Grüße, Andreas |
AW: Codeoptimierung lieber abschalten
Zitat:
OK, ernsthaft: Das mache ich auch so, allerdings nicht durch ifdef im Sourcecode sondern durch Setzen der Option in der Release-Config. Das ifdef hat den Nachteil, dass es nicht so simpel ist, die Optimierung einzuschalten, weil man dafür den Sourcecode ändern muss. |
AW: Codeoptimierung lieber abschalten
Zitat:
|
AW: Codeoptimierung lieber abschalten
Zitat:
Konkrete Beispiele fände ich aber interessant. |
AW: Codeoptimierung lieber abschalten
Zitat:
|
AW: Codeoptimierung lieber abschalten
Zitat:
Delphi-Quellcode:
Das sagt ziemlich wenig, ohne den Rest der Methode, aber selbst wenn ich die hier poste könnte, wäre sie ohne Kontext nur sehr schwer verständlich. Laserdata ist ein Array of TLaserData-Records, die optional initialisiert werden, wenn es die entsprechenden Dateien gibt. FReader wurde vor dem zugehörigen try mit NIL initializiert.
finally
// Wenn Optimization on ist, gibt es in Delphi 2007 eine AccessViolation in TLaserData.Done bei // der Freigabe von FReader. Ohne passiert das nicht. // -- 2021-04-16 twm {$OPTIMIZATION OFF} for LaserNo := Low(LaserData) to High(LaserData) do LaserData[LaserNo].Done; FreeAndNil(TrigStream); FreeAndNil(OutStream); end; Result := FRes; end; {$IFDEF OPTIMIZATION_IS_ON} // Ab hier kann man Optimization wieder einschalten. Frueher - also z.B. direkt nach der // for-schleife ging es nicht. // -- 2021-04-16 twm {$OPTIMIZATION ON} {$ENDIF} procedure TLaserData.Done; begin FreeAndNil(FReader); end; Andere Beispiele (ich meine es waren noch zwei weitere), finde ich nicht, die müssen im Source von einzelnen internen Tools gewesen sein, und davon haben wir zuviele um den mal eben zu grep-en. Obiges Beispiel kann ich noch nicht auf Delphi 10.2 portieren, da es immernoch einen Rechner mit Windows XP gibt, auf dem es laufen muss, deshalb weiß ich nicht, ob der Fehler dort noch auftreten würde. |
AW: Codeoptimierung lieber abschalten
Also ich kann nur sagen, ich benutze die Optimierung immer und bin bisher noch nicht damit gegen eine Wand gefahren. Aber natürlich gibt es immer und überall Fehler, darum testet man ja - sowohl automatisiert als auch mit Menschen.
Hier mal ein paar Beispiele wie Fehler zu handhaben sind: ![]() ![]() ![]() Sherlock |
AW: Codeoptimierung lieber abschalten
Zitat:
Zitat:
|
AW: Codeoptimierung lieber abschalten
Einfach noch eine Config hinzufügen?
Release Debug (wie Release, nur ohne Debuginfos) Und dann kann man nochmal davon ableiten und Varianten mit/ohne Codeoptimierung hinzufügen, oder, wie bereits erwähnt, dann das wenigstens in beiden Configs abschalten, damit man auch das debuggt, was auch der Kunde bekommt. Alternativ mit externen Debuginfos kompilieren ... jenachdem ob die Debuginfodateien (TDS) daneben liegen, ist es mit oder ohne, aber die Programmdateien selber sind immer identisch. |
AW: Codeoptimierung lieber abschalten
Ich meine gehört zu haben :?, dass im Optimierungsfalle Schleifen ggf. in die andere Richtung abgearbeitet werden, was zu 'Seiteneffekten' führen kann.
|
AW: Codeoptimierung lieber abschalten
Ohne einen Beleg dafür ist das nur Angstmacherei.
|
AW: Codeoptimierung lieber abschalten
Zitat:
Dann könnte man es wieder zentral ein/ausschalten. |
AW: Codeoptimierung lieber abschalten
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Delphi-Quellcode:
Der generierte Code sieht so aus:
procedure Test;
var i: Integer; begin for i := 0 to 9 do ShowMessage(1.ToString); end; Anhang 55709 //EDIT: Ach ja, wenn man im Assemblercode nicht die Variable, sondern das Register anspricht, kommt man auch dran. Das kann jeder mit Optimierung testen:
Delphi-Quellcode:
procedure Test;
var i, b: Integer; begin for i := 0 to 9 do begin asm mov b, ebx end; ShowMessage(b.ToString); end; end; |
AW: Codeoptimierung lieber abschalten
Zitat:
|
AW: Codeoptimierung lieber abschalten
Zitat:
Egal, ob aus dem
Delphi-Quellcode:
der Compiler das macht.
for i := 1 to 9 do
Write(i);
Delphi-Quellcode:
Am Ende kommt das Gleiche bei raus.
for i := 8 downto 0 do
Write(9 - i); Aber kommt wer auf die saudumme Idee nach der Schleife auf i zugreifen zu wollen, dann ist er selbst Schuld. @jaenicke: Mit 64 Bit stirbt der Inline-Assembler eh aus. Und wenn i mal nicht in ebx liegt, dann hat dein Code eh ein Problem. Wenn du im Assembler auf "i" zugreifst, dann weiß der Compiler in welchem Register/Stack die Variable liegt und dass hier nicht optimiert werden kann/soll. Auch mit Pointern kann man da Mist bauen.
Delphi-Quellcode:
for i := 0 to 9 { step 2 } do begin
ShowMessage(i.ToString); // 0 2 4 6 8 Inc(PInteger(@i)^); end; |
AW: Codeoptimierung lieber abschalten
Zitat:
![]() Sherlock |
AW: Codeoptimierung lieber abschalten
Ich korrigiere mal einige Aussagen bezüglich "rückwärts zählende Schleifen".
Sofern die Zählvariable innerhalb des Schleifenrumpfes benutzt wird, fügt der Compiler zusätzlich zu der Zählvariable, welche sich im korrekten Wertebereich bewegt zusätzlich eine Variable ein, die er nutzt, um auf 0 runter zu zählen. Diese wird aber nicht wie etwa von Himitsu skizziert für irgendetwas anderes genutzt als für den Schleifen Code an sich. Interessanterweise passiert dies in dem geposteten Code nicht mal, sondern nur, wenn lower und/oder upper bound variabel sind. Das auf 0 runter zählen ist eine gängige Optimierung da hierbei nach dem Dekrement direkt ein bedingter Sprungbefehl stehen kann, anstatt zuerst einen Vergleich auf die obere Grenze - je nachdem wie viele Register für den Code gebraucht werden, kann das aber auch eher nachteilig sein, gerade unter 32bit hat man nur eine Handvoll davon. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz