Optimierungen durch Compiler in einem rekursiven Programm

8

Ich wurde von der Optimierung der Tail-Call-Frage Was ist Tail Call Optimization <

Also habe ich beschlossen zu sehen, wie ich es in normalem C machen kann.

Also habe ich die 2 faktoriellen Programme geschrieben, 1. wo die Tail Call Optimierung angewendet werden kann. Ich nenne diese Tatsache Funktion als Tatsache (n, 1).

%Vor%

2. ist die normale Rekursion, bei der mehrere Stapelrahmen benötigt werden.

%Vor%

Dies ist die Assembly, die von einem 32-Bit-Compiler für den ersten mit -O2

generiert wird %Vor%

Dies ist die Assembly, die von einem 32-Bit-Compiler für letztere mit -O2 generiert wird.

%Vor%

Kompilieren Sie beide Programme, und sehen Sie sich die erzeugte Assembly an. Beide Programme haben immer noch rekursive Aufrufe. Aber, wenn ich kompiliere mit -O2-Option (Assembly oben gepostet) in ersterem, sehe ich überhaupt keine rekursiven Aufrufe und so denke ich, gcc tut Tail Call Optimierung Zeug.

Aber wenn ich das letztere mit der Option -O2 kompiliere, entfernt es auch die rekursiven Aufrufe und stellt statt dessen eine ziemlich große Anzahl von Assemblerbefehlen im Vergleich zu dem, was mit dem vorherigen on -O2 passiert.

Ich wollte genau verstehen, was der Compiler in letzterem macht und warum er nicht in die Assembly transformiert werden konnte, die durch den Example selbst mit O4 erzeugt wurde.

    
0xhacker 22.03.2012, 14:37
quelle

3 Antworten

5

Programm 2 tut long long Berechnungen, progtlram 1 nicht.

    
n.m. 22.03.2012 18:05
quelle
4

Der Unterschied ist, dass die erste Version eine Variable int für die Berechnung verwendet, die dann am Ende auf unsigned long long erweitert wird, während die letzte Version unsigned long long den ganzen Weg verwendet.

    
Simon Richter 22.03.2012 18:10
quelle
0

Der Compiler scheint die rekursiven Aufrufe in Schleifen optimiert zu haben. Beachten Sie, dass Ihr C-Code nur Vorwärtszweige hat (wenn-dann-sonst), aber der Assembler hat Rückwärtszweige (Schleifen).

Wenn Sie wirklich eine Tail-Call-Optimierung in Aktion sehen wollen, rufen Sie eine andere Funktion auf. Natürlich ist das keine Rekursion, aber der Compiler ist zu schlau für kleine Testfälle wie diese.

    
ams 22.03.2012 20:20
quelle