2013-02-25 17 views
6

Ich bin sicher, dass jeder weiß golang, dass blog post hier.Warum ist Gccgo in diesem speziellen Fall langsamer als GC?

Als ich es noch einmal las, fragte ich mich, ob die Verwendung von gccgo anstelle von go build die Geschwindigkeit etwas erhöhen würde. In meinem typischen Anwendungsfall (wissenschaftliche Berechnungen) ist eine gccgo -generierte binäre immer schneller als eine go build -generierte.

Also, packen gerade diese Datei: havlak6.go und kompilieren:

go build havlak6.go -O havlak6_go 
gccgo -o havlak6_gccgo -march=native -Ofast havlak6.go 

Überraschung!

$/usr/bin/time ./havlak6_go 
5.45user 0.06system 0:05.54elapsed 99%CPU 

$/usr/bin/time ./havlak6_gccgo 
11.38user 0.16system 0:11.74elapsed 98%CPU 

Ich bin neugierig und möchte wissen, warum ein "optimierender" Compiler langsamer Code produziert.

Ich versuchte gprof auf gccgo erzeugten binären zu verwenden:

gccgo -pg -march=native -Ofast havlak6.go 
./a.out 
gprof a.out gmon.out 

ohne Glück:

Flat profile: 

Each sample counts as 0.01 seconds. 
no time accumulated 

Wie Sie den Code sehen kann, ist nicht wirklich profiliert worden.

Natürlich las ich this, aber wie man sehen kann, nimmt das Programm 10+ Sekunden auszuführen ... Die Anzahl der Proben sollte> 1000

Ich habe auch versucht:

rm a.out gmon.out 
LDFLAGS='-g -pg' gccgo -g -pg -march=native -Ofast havlak6.go 
./a.out 
gprof 

Kein Erfolg weder noch.

Wissen Sie, was los ist? Haben Sie eine Vorstellung davon, warum gccgo, mit all seinen Optimierungsroutinen nicht schneller als gc in diesem Fall ist?

go Version: 1.0.2 gcc Version: 4.7.2

EDIT:

Oh, ich vergaß zu erwähnen, ganz ... ich natürlich versucht pprof auf dem gccgo -Generated binär. Hier .. ist ein top10:

Welcome to pprof! For help, type 'help'. 
(pprof) top10 
Total: 1143 samples 
    1143 100.0% 100.0%  1143 100.0% 0x00007fbfb04cf1f4 
     0 0.0% 100.0%  890 77.9% 0x00007fbfaf81101e 
     0 0.0% 100.0%  4 0.3% 0x00007fbfaf8deb64 
     0 0.0% 100.0%  1 0.1% 0x00007fbfaf8f2faf 
     0 0.0% 100.0%  3 0.3% 0x00007fbfaf8f2fc5 
     0 0.0% 100.0%  1 0.1% 0x00007fbfaf8f2fc9 
     0 0.0% 100.0%  1 0.1% 0x00007fbfaf8f2fd6 
     0 0.0% 100.0%  1 0.1% 0x00007fbfaf8f2fdf 
     0 0.0% 100.0%  2 0.2% 0x00007fbfaf8f4a2f 
     0 0.0% 100.0%  1 0.1% 0x00007fbfaf8f4a33 

Und das ist, warum ich für etwas anderes suchen.

EDIT2:

Da es scheint, dass jemand meine Frage will geschlossen werden, ich nicht gprof aus heiterem Himmel zu verwenden versuchte: https://groups.google.com/d/msg/golang-nuts/1xESoT5Xcd0/bpMvxQeJguMJ

+0

Leute noch [* glauben an gprof als der kanonische Profiler. *] (Http://stackoverflow.com/a/1779343/23771). Einige Punkte: 1) gprof ist nur nützlich für CPU-gebundene Programme mit flachen Call-Stacks, ohne Rekursion, für die es alle Symbole hat. 2) Die Compiler-Optimierung macht nur einen Unterschied in engen inneren Schleifen oder Routinen, die in Ihrem Code als viel bezeichnet werden und die Funktionen selbst nicht aufrufen (wie Speicherzuweisung usw.). Compiler-Optimierung macht nicht nur alles schneller. –

+0

Ja, ich habe es für gprof. Und ich stimme Ihnen mit den Compiler-Optimierungen zu. Allerdings würde ich mit einem optimierungsfähigen Compiler keine schlechteren Leistungen erwarten. Leistungen sollten gleich oder besser sein. Wenn nicht, gibt es Raum für Verbesserungen, und ich würde gerne verstehen, warum :) –

+0

Das einzige Timing, das ich jemals tue, ist Ende-zu-Ende, möglicherweise wiederholt 10^n mal und geteilt durch das, und ich suche nicht mehr als 3 Stellen Genauigkeit. Es gibt Lärm und es ist mir egal. Dann benutze ich zufällige Pause, um nach Möglichkeiten zu suchen, um es schneller zu machen. Wenn es nicht schon wie ein Schwamm gequetscht ist, werde ich Wege finden, und dann kann ich es noch einmal tun. Wenn ich nach mehreren Zyklen einen abnehmenden Ertrag erreiche und der PC meistens in meinen generierten Anweisungen ist, dann schalte ich den Optimierer ein, was es vielleicht 10% schneller macht. Whoopee. –

Antwort

2

Ausführen des gccgo generierte binäre unter Valgrind scheint um anzuzeigen, dass gccgo einen ineffizienten Speicherzuordner hat. Dies könnte einer der Gründe sein, warum gccgo 4.7.2 langsamer ist als go 1.0.2. Es ist unmöglich, eine von go 1.0 generierte Binärdatei auszuführen.2 unter Valgrind, so ist es schwer zu bestätigen, ob die Speicherzuweisung in diesem Fall das primäre Leistungsproblem von gccgo ist.

+0

Danke für die Erwähnung von 'Valgrind'. Das ist das allererste Mal, dass ich mich mit dem Profiling beschäftige, und obwohl gprof der Profiler war ... ich lag falsch :) Es scheint jedoch, dass 'Valgrind' ein C-only Profiler/Profiling Framework ist. Es beschwert sich über nicht initialisierte Werte und scheint überhaupt nicht "wegzukommen" ... Könntest du etwas näher ausführen? –

+0

Ich habe 'valgrind --tool = callgrind' und KCacheGrind verwendet, um das Verhalten des gccgo-generierten Codes zu untersuchen. Valgrinds Callgrind ist auch in der Lage, viele Nicht-C-Codes zu verwenden, aber leider trifft er Annahmen, die von go1.0.2-generierten Binärdateien verletzt werden. https://code.google.com/p/go/issues/detail?id=782 –

0

Denken Sie daran, go build auch standardmäßig auf statische Verknüpfung, so für einen Vergleich zwischen Äpfeln und Äpfeln sollten Sie gccgo die -static oder -static-libgo Option geben.

Verwandte Themen