Ich schreibe eine kompilierte Sprache zum Spaß, und ich habe vor kurzem einen Kick bekommen, um meinen optimierenden Compiler sehr robust zu machen. Ich habe mehrere Möglichkeiten gefunden, einige Dinge zu optimieren, zum Beispiel 2 + 2 ist immer 4, also können wir diese Mathematik zur Kompilierzeit machen, wenn (falsch) {...} komplett entfernt werden kann usw., aber jetzt Ich habe Schleifen bekommen. Nach einigem Nachdenken denke ich, dass ich nicht gerade Loop Enrolling versuche, aber es ist immer noch eine Optimierungstechnik. Lassen Sie mich erklären.Optimierung von "statischen" Schleifen
Nehmen Sie den folgenden Code.
String s = "";
for(int i = 0; i < 5; i++){
s += "x";
}
output(s);
Als Mensch, kann ich hier sitzen und sagen, dass dies 100% der Zeit zu
output("xxxxx");
So äquivalent zu gehen, in anderen Worten, diese Schleife „kompiliert werden aus "ganz Es ist nicht das Abrollen der Schleife, sondern das, was ich "vollständig statisch" nenne, dh es gibt keine Eingaben, die das Verhalten des Segments verändern würden. Meine Idee ist, dass alles, was vollständig statisch ist, in einen einzigen Wert aufgelöst werden kann, alles, was auf Eingaben beruht oder konditionale Ausgaben erzeugt, kann natürlich nicht weiter optimiert werden. Was muss ich aus der Sicht der Maschine beachten? Was macht eine Schleife "vollständig statisch?"
Ich habe drei Arten von Schleifen gefunden, die ich herausfinden muss, um zu kategorisieren. Schleifen, die nach jedem Lauf immer denselben Maschinenzustand haben, unabhängig von Eingaben, Schleifen, die NIE abgeschlossen werden, und Schleifen, die ich nicht in die eine oder andere Richtung herausfinden kann. In dem Fall, dass ich es nicht herausfinden kann (es ändert sich bedingt, wie oft es basierend auf dynamischen Eingaben laufen wird), mache ich mir keine Sorgen über die Optimierung. Schleifen, die unendlich sind, werden ein Kompilierfehler/eine Kompilierung sein, wenn sie vom Programmierer nicht spezifisch unterdrückt werden, und Schleifen, die jedes Mal gleich sind, sollten direkt überspringen, um die Maschine in den richtigen Zustand zu versetzen, ohne Schleife.
Der Hauptfall natürlich zu optimieren ist die statische Schleife Iterationen, wenn alle Funktionsaufrufe innerhalb sind auch statisch. Das Bestimmen, ob eine Schleife dynamische Komponenten hat, ist einfach genug und wenn sie nicht dynamisch ist, muss sie statisch sein. Was ich nicht herausfinden kann ist, wie man erkennt, ob es unendlich sein wird oder nicht. Hat jemand darüber irgendwelche Gedanken? Ich weiß, dass dies eine Teilmenge des Halteproblems ist, aber ich fühle, dass es lösbar ist. Das Halteproblem ist ein Problem aufgrund der Tatsache, dass man für einige Teilmengen von Programmen nicht sagen kann, dass es für immer laufen könnte, es mag nicht sein, aber ich möchte diese Fälle nicht berücksichtigen, ich möchte nur die Fälle betrachten wo es stehen bleibt, oder es wird nicht aufhören, aber zuerst muss ich zwischen den drei Zuständen unterscheiden.
Um eine Vorstellung davon zu bekommen, was derzeit in dieser Zeile unterstützt wird, möchten Sie vielleicht etwas über die Einschränkungen von 'constexpr' im neuen C++ - Standard lesen. –
Wenn Sie statisch feststellen können, dass die Schleifenbedingung immer wahr ist und es keine andere Möglichkeit gibt, die Schleife zu beenden, wissen Sie, dass die Schleife nicht beendet wird. –
In Ihrem Beispiel wissen Sie nicht unbedingt, dass String s nicht auch von einer anderen Datei modifiziert wird, die auf extern verweist und sie in einem parallelen Thread modifiziert. – TJD