13.07.2015 Aufrufe

Vergleich des Oberon x86−Compilers mit dem GNU gcc - Computer ...

Vergleich des Oberon x86−Compilers mit dem GNU gcc - Computer ...

Vergleich des Oberon x86−Compilers mit dem GNU gcc - Computer ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3 Mittel Effektperm 79 107 96 99 71 90,4 −101,58towers 73 136 78 69 59 83 −108,98queens 68 89 66 66 66 71 −120,98intmm 58 86 34 38 37 50,6 −141,38mm 67 126 44 51 47 67 −124,98puzzle 350 738 393 393 393 453,4 261,42quick 81 148 73 71 70 88,6 −103,38bubble 112 239 88 78 79 119,2 −72,78tree 94 139 85 83 96 99,4 −92,58fft 156 400 109 72 72 161,8 −30,18dhry 899 1237 723 741 537 827,4 635,42Mittel 185,18 313,18 162,64 160,09 138,82 191,98Effekt −6,8 121,2 −29,35 −31,89 −53,16Variation explained by Compiler: 6,40%Variation explained by Kernel: 85,31%Unexplained variation: 8,29%Erwartungsgemäss ist der ist der durch die Kernel erzeugte Anteil an der Varianz derMesswerte <strong>mit</strong> 85.5% am grössten. Der Compiler ist nur für etwa 6% der Varianz derMesswerte verantwortlich. Die restlichen 8.5% der Varianz müssen so<strong>mit</strong> <strong>mit</strong> denInteraktionen zwischen Kernel und Compiler zusammenhängen.Um nun die Wirkung der einzelnen Optimierungsstufen beurteilen zu können, müssen dieKernel offenbar getrennt weiterbetrachtet werden.4. Die <strong>gcc</strong> OptimierungsstufenAls nächtes wollen wir uns einen Ueberblick über die Optimierungen und ihren Einfluss aufdie Gesamtperformance verschaffen. Die Optimierungen sind in 4 grobe Klassen eingeteilt.Diese Klassen entsprechen genau den 4 Optimierung−Stufen (O0, O1, O2 und O3) <strong>des</strong> <strong>gcc</strong>.Die Performance−Wert sind auf den <strong>Oberon</strong>−Compiler normiert.Als erstes fällt einem auf, dass der <strong>Oberon</strong>−Compiler anscheinend gar nicht so schlecht ist.Diese Schlussfolgerung ist allerdings ein bisschen gefährlich. Der Performance−Wert hängtselbstverständlich nicht nur vom Compiler, sondern auch vom Betriebssystem etc. ab.


3puzzle3queens3quick2,52,52,5runtime21,51runtime21,51runtime21,510,50,50,5000<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3compilercompilercompiler3towers3fft3perm2,52,52,5runtime21,51runtime21,51runtime21,510,50,50,5000<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3compilercompilercompiler3bubble3dhrystone3mm2,52,52,5runtime21,51runtime21,51runtime21,510,50,50,5000<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3compilercompilercompiler3intmm3tree2,52,5runtime21,51runtime21,510,50,500<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3<strong>Oberon</strong> <strong>gcc</strong> −O0 <strong>gcc</strong> −O1 <strong>gcc</strong> −O2 <strong>gcc</strong> −O3compilercompilerAls erstes ist wohl zu bemerken, dass der <strong>Oberon</strong>−Compiler in je<strong>dem</strong> Kernel schneller ist, alsder nicht−optimierende <strong>gcc</strong>. Da die optimierten <strong>gcc</strong>−Läufe ein deutlich differenzierteres Bildergeben ist, sei diese Tatsache für den Augenblick zur Seite gestellt.Eine auffällige Differenz ergibt sich bei Fliesspunkt−intensivem Code. Sowohl in der fft alsauch bei FP−Matrix−Multiplikation schneidet der <strong>gcc</strong> deutlich besser ab.Hingegen scheinen Funktionsaufrufe im <strong>Oberon</strong>−Code deutlich effizienter zu sein: im perm−Kernel schneidet der <strong>gcc</strong> auch bei eingeschalteten Optimierungen schlechter ab, als der<strong>Oberon</strong>−Compiler. Erst durch das Hinzuschalten von Function Inlining kann der <strong>gcc</strong> <strong>mit</strong> <strong>dem</strong><strong>Oberon</strong>−Compiler <strong>mit</strong>halten.


Eine Schwäche <strong>des</strong> <strong>Oberon</strong>−Compiler scheinen Array− bzw. Matrix−Zugriffe zu sein. In allenKernels, die Array−Zugriffe testen (mm, intmm, quick und bubble) schneidet der Compilerschlechter ab, als der <strong>gcc</strong>. Bemerkenswert ist hier, dass der <strong>gcc</strong> sehr stark von den Basis−Optimierungen (lokale CSE und Sprungoptimierungen) zu profitieren scheint.Interessant ist, dass Paar Quicksort vs. Bubble−Sort zu betrachten. Während beide vieleArray−Zugriffe durchführen (und daher der <strong>gcc</strong> schneller sein sollte, als der <strong>Oberon</strong>−Compiler), ist das Bild beim rekursiven Quicksort viel ausgeglichener als beim iterativenBubblesort.Prinzipiell lässt sich sagen, dass der <strong>gcc</strong>−Code <strong>mit</strong> eingeschalteten Basis−Optimierungensehr häufig schneller ist als der <strong>des</strong> <strong>Oberon</strong>−Compiler, es sei denn der Kernel enthält einengrossen Anteil an Prozeduraufrufen. Der weitere Leistungsgewinn (−O2 und −O3) ist häufigsehr klein oder gar negativ!Die logische Vorgehensweise wäre jetzt eigentlich, sich die Basis−Optimierungen genaueranzuschauen. Leider ist das aber nicht möglich. Der aktuelle <strong>gcc</strong> erlaubt es nicht, dieseOptimierungen einzeln zu aktivieren und zu deaktivieren. Wir können also keine genaueAussage darüber machen, welche Optimierungen in diesem Paket den grössten Effekterzielt.Anstatt<strong>des</strong>sen werden wir im nächsten Schritt die separat einschaltbaren Optimierungengenauer betrachten, um herauszufinden, ob es darunter eine gibt, die einen überragendenEinfluss hat.5. Optimierungen im DetailZiel dieses Experiments ist, herauszufinden, welche der "weitergehenden" Optimierungen<strong>des</strong> <strong>gcc</strong>, welchen Einfluss auf die Leistung <strong>des</strong> Co<strong>des</strong> haben. Dafür wurden, ausgehend vomoptimierenden Compiler−Lauf, die einzelnen Optionen variiert.Aufteilung der <strong>gcc</strong>−Optimierungen im ExperimentIm Experiment wurde der aktuell verfügbare egcs 1.1.2 verwendet. Für die Berechnung derBeiträge der einzelnen Optimierungen, wurden sie in "Paketen" zusammengefasst. Leitfadenbei der Zusammenstellung war, möglichst ähnliche Optimierungen zusammenzufügen, bzw.mehrere <strong>gcc</strong>−Optionen, die verschiedene Varianten derselben Optimierung steuern,zusammenzunehmen. Mit diesem Ansatz wurde versucht, die Anzahl Parameter, die zuvariieren sind, in einem vernünftigen Rahmen zu halten. Sollte sich herausstellen, dass einPaket sehr starken Einfluss hat, oder stark <strong>mit</strong> einem anderen interagiert, so können sie ineinem zweiten Schritt noch aufgeteilt werden.Im folgenden sind die Pakete jeweils <strong>mit</strong> den genauen getesteten Compilerschalternangegeben:1. Local Common Subexpression EliminationEs ist zwar nicht möglich, die LCSE aus− oder einzuschalten, es gibt aber dennoch eineganze Reihe von Optionen, die das Verhalten der LCSE steuern. Sie wurden alle in


diesem Paket zusammengefasst.Die Schalter sind:−ffunction−cse−fforce−mem−fforce−addr−fcse−follow−jumps−fcse−skip−blocks2. Global Common Subexpression EliminationSchaltet die GCSE ein oder aus. Schalter:−fgcse3. Function InliningEs gibt die Möglichkeit, Function Inlining nur für Funktionen einzuschalten, die im Quelltextals "inline" markiert sind. Da aber der <strong>Vergleich</strong> zum <strong>Oberon</strong>−Compiler gesucht ist, und esdiese Möglichkeit in <strong>Oberon</strong> nicht gibt, wird nur zwischen gar kein FI und heuritischem FI(d.h. der Compiler versucht, herauszufinden, bei welcher Funktion es sich lohnt, sie direkteinzufügen) unterschieden.Compilerschalter kein FI:−fno−inlineCompilerschalter heuristisches Inlining:−finline4. Instruction SchedulingDer <strong>gcc</strong> bietet die Möglichkeit, das Scheduling nach der Registervergabe ein zweites Maldurchzuführen, um zu verhindern, dass Spilling Code den Schedule zerstört. Für denersten Schritt wurden beide Durchläufe aktiviert, <strong>mit</strong> der Option, sie später nochaufzutrennen.Compilerschalter:−fschedule−insns−fschedule−insns25. Loop OptimizationsAlle Schleifenoptimierungen in einem Paket:−fstrength−reduce−funroll−loops−fmove−all−movables−freduce−all−givs−frerun−cse−after−loop (durch −funroll−loops impliziert)−frerun−loop−opt6. DiverseEine ganze Reihe "kleinerer" Optimierungen, die sich im Wesentlichen <strong>mit</strong> Spezialitäten<strong>des</strong> Assemblerco<strong>des</strong> beschäftigen. Es handelt sich dabei um die folgenden:−fregmove:Optimiert das Verschieben von Registern.−fo<strong>mit</strong>−frame−pointer:Optimiert den Stackframe von Prozeduren, in<strong>dem</strong> kein Frame−Pointer angelegt wird.


−fthread−jumps:Optimiert konditionale Sprünge auf konditionale Sprünge.−fdefer−popVersucht, das Freigeben von Stackframes am Stück zu machen, statt je<strong>des</strong> Element auf<strong>dem</strong> Stack einzeln freizugeben.Konstante OptionenDer GCC bietet die Möglichkeit, strikte Annahmen über die Typen von Objektenund Adressreferenzen zu machen (−fstrict−aliasing). Da <strong>Oberon</strong> ein rechtstarkes Typing hat, kann man davon ausgehen, dass Modifikationen vonOptimierungen, die aufgrund dieses Schalters aktiviert werden, auch im<strong>Oberon</strong>−Compiler Sinn machen. Es gibt daher keinen Grund, diese Option auszuschalten, daein <strong>Oberon</strong>−Compiler nicht auf schwächere Typisierungsbedingungen Rücksicht nehmenmuss.DesignUm zuverlässige Daten zu erhalten, müssen wir die Messungen replizieren. Wir haben unsfür 5 Wiederholungen entschieden. Sollten die Messungen grössere Schwankungenenthalten, hätten wir weitere Messungen machen können. Wie sich herausstellte, war dasaber nicht nötig.Eine mögliche Design−Variante wäre ein Full−Factorial−Design <strong>mit</strong> Replikation. In unseremFall wäre die Laufzeit wahrscheinlich keine Hindernis gewesen. Wir haben uns trotz<strong>dem</strong>gegen diese Variante entschieden, da wir immerhin schon 6 Faktoren haben und die Analyseder Daten sehr komplex und unübersichtlich werden würde.Statt<strong>des</strong>sen haben wir uns entschieden, ein 2 6 3 ∗5 Design zu verwenden.ResultateIn den folgenden Diagrammen sind einmal die Effekte (Balkendiagramme) und der Einflussauf die Varianz (Kuchendiagramme) dargestellt. Der Wert in Klammern auf denKuchendiagrammen bezeichnet die maximale Varianz, die durch die Optimierungen zuerreichen war. Effekte, die kleiner als 0.1 % waren, wurden in der graphischen Darstellungnicht berücksichtigt.


dhrystone (4.41%)fft (0.29%)intmm (0.43%)local commonsubexpressioneliminationglobal commonsubexpressioneliminationvarious−local commonsubexpressioneliminationglobal commonsubexpressioneliminationvarious−measurementerrorlocal commonsubexpressioneliminationglobal commonsubexpressioneliminationvarious−measurementerrorfunction inliningfunction inliningfunction inlininginstructionschedulingloopoptimizationsinstructionschedulingloopoptimizationsinstructionschedulingloopoptimizationslocal common subexpressioneliminationlocal common subexpressioneliminationlocal common subexpressioneliminationoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsvariousvariousvarious−110 −90 −80 −70 −60 −50 −40 −30 −20 −10 0 10effect−4 −3 −2 −1 0effect−2 −1 0 1effectbubble (1.10%)mm (0.27%)queens (0.41%)local commonsubexpression eliminationglobal com−mon subex−pressionfunctioninlininginstructionschedulingloopoptimizationsvariousmeasurementerrorlocal commonsubexpressioneliminationglobal commonsubexpressioneliminationfunction inlininginstructionschedulingloopoptimizationsvarious−measurementerrorlocal commonsubexpressioneliminationglobal commonsubexpressioneliminationfunction inlininginstructionschedulingloopoptimizationsvarious−measurementerrorlocal common subexpressioneliminationlocal common subexpressioneliminationlocal common subexpressioneliminationoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsvariousvariousvarious−4 −3 −2 −1 0 1 2 3 4effect−1 0 1 2effect−2 −1 0 1 2effectAls erstes ist wohl zu bemerken, dass bei keinem der getesteten Kernel die Optimierungenmehr als etwa 4% an Varianz bewirken konnten. So gesehen sind die, durch dieOptimierungen zu erreichenden, Leistungssteigerungen nur noch mässig interessant.Es lässt sich sehr schlecht eine Optimierung ausmachen, die immer oder wenigstens häufigeinen grossen Einfluss auf die Leistung hat. Während einmal die Variation der local CSE sichstark bemerkbar macht (bubble), hat sie bei einigen anderen Kernel kaum (mm, intmm) bzw.sogar negativen Einfluss (puzzle). Eine ähnliche Argumentation lässt sich leider für alleanderen Optimierungen ebenfalls führen.


quick (0.09%)puzzle (0.40%)tree (0.51%)global commonsubexpressioneliminationfunction inliningvariousmeasurementerrorlocal commonsubexpressioneliminationglobal commonsubexpressioneliminationfunction inliningloopoptimizationsvarious−local commonsubexpressioneliminationglobal commonsubexpressioneliminationfunction inlininginstructionschedulingloopoptimizationsvariousmeasurementerrorlocal common subexpressioneliminationlocal common subexpressioneliminationlocal common subexpressioneliminationoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsvariousvariousvarious−2 −1 0 1 2effect−7 −6 −5 −4 −3 −2 −1 0 1 2 3 4 5 6 7 8 9 10 11effect−2 −1 0 1 2 3 4 5effectperm (3.52%)towers (4.65%)local commonsubexpressioneliminationfunction inlininginstructionschedulingloopoptimizationsvarious−measurementerrorlocal commonsubexpressioneliminationglobal commonsubexpressioneliminationfunction inlininginstructionschedulingloopoptimizationsvarious−measurementerrorlocal common subexpressioneliminationlocal common subexpressioneliminationoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsoptimizationsglobal common subexpressioneliminationfunction inlininginstruction schedulingloop optimizationsvariousvarious−12−11−10 −9 −8 −7 −6 −5 −4 −3 −2 −1 0 1 2effect−10 −9 −8 −7 −6 −5 −4 −3 −2 −1 0 1 2 3effectSinnvolle Schlussfolgerungen lassen sich also aus diesen Daten allerdings kaum ziehen.Interessant ist allerdings zu sehen, dass die Optimierungen im Verhältnis zur Performancenur sehr wenig bringen. Der Anteil liegt in den meisten Fällen unter 1%!


SchlussfolgerungenTrotz der Tatsache, dass die präsentierten Zahlen <strong>mit</strong> Vorsicht genossen werden müssen,weil Effekte durch oo2c und Betriebssystem nur schlecht quantifiziert werden können, lassensich gewisse Trends feststellen.Der <strong>Oberon</strong>−Compiler kann in einigen Bereichen problemlos <strong>mit</strong> <strong>dem</strong> <strong>gcc</strong> an Code−Qualität<strong>mit</strong>halten. Insbesondere Funktionsaufrufe sind seine Stärke.Auf der anderen Seite sind sowohl Floating−Point intensiver Code, als auch Array−Zugriffenicht sehr überzeugend. Hier kann der <strong>gcc</strong> <strong>mit</strong> der lokalen CSE und den Sprung−optimierungen sehr viel an Leistung aus <strong>dem</strong> Code herausholen.Interessanterweise ist der Einfluss der übrigen Optimierungen verhältnismässig gering. Soliegen ihre Effekte im Bereich von einigen, wenigen Prozent. Zu<strong>dem</strong> ist es fast unmöglich,Optimierungen anzugeben, die in allen Fällen mehr Leistung bringen. Der Effekt derOptimierungen ist sehr stark vom Kernel abhängig. Eine genauere Untersuchung über dieZusammensetzung von "durchschnittlichem" <strong>Oberon</strong>−Code liegt aber ausserhalb <strong>des</strong>Bereichs dieses Berichts. Der einzige Kernel, den man als durchschnittlich bezeichnenkönnte ist wohl der Dhrystone Benchmark. Hier zeigt sich dann aber auch, dass, bis aufFunction Inlining, keine der zusätzlichen (d.h. über die Basisoptimierungen hinaus−gehenden) Optimierungen durchschlagenden Erfolg hat. Dies zeigt sich sowohl in denabsoluten Zahlen <strong>des</strong> zweiten Tests, als auch in der genaueren Analyse <strong>des</strong> dritten Tests.Abschliessend lässt sich wohl sagen, dass die einzige Optimierung, die ein vernünftiges"Preis/Leistungsverhältnis" bezüglich Leistungssteigerung und Implementationsaufwand dieCommon Subexpression Elimination (<strong>mit</strong> Constant/Copy Propagation) und denSprungoptimierungen (evtl. zusammen <strong>mit</strong> einer Dead−Store/Code−Eliminination) ist. Da dieImplementation all dieser Optimierungen auf ähnlichen Datenflussalgorithmen basiert, solltees verhältnismässig wenig Mehraufwand sein alle drei, statt nur einer davon zuimplementieren.Referenzen[Muchnick][Dragon][oo2c][Jain}Steven S. Muchnik: Advanced Compiler Design & ImplementationMorgan Kaufmann Publishers, 1997.Aho, Sethi, Ullman: Compilers, Principles, Techniques, and ToolsAddison Wesley, 1988http://www.uni−kl.de/OOC/Raj Jain: The Art of <strong>Computer</strong> Systems Performance AnalysisJohn Wiley & Sons, 1991

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!