2013-02-25 12 views
6

Jestem pewien, że wszyscy znający golang wiedzą, że tutaj jest blog post.Dlaczego w tym przypadku gccgo jest wolniejsze niż gc?

Czytając to jeszcze raz, zastanawiałem się, czy użycie gccgo zamiast go build zwiększyłoby nieco prędkość. W moim typowym przypadku użycia (obliczenia naukowe) wygenerowany plik binarny o wartości gccgo jest zawsze szybszy niż generowany przez gccgo.

Tak, tylko pobrać ten plik: havlak6.go i skompilować go:

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

niespodzianka!

$/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 

Jestem ciekawy i chcę wiedzieć, dlaczego kompilator "optymalizujący" produkuje wolniejszy kod.

Próbowałem użyć gprof na gccgo generowanego binarny:

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

bez powodzenia:

Flat profile: 

Each sample counts as 0.01 seconds. 
no time accumulated 

Jak widać kod nie został właściwie wyprofilowane.

Oczywiście czytałem this, ale jak widać, program trwa 10+ sekund, aby wykonać ... Liczba próbek powinna być> 1000.

Próbowałem również:

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

Brak sukcesów.

Czy wiesz, co jest nie tak? Czy masz pojęcie, dlaczego gccgo, w którym wszystkie procedury optymalizacyjne nie są w tym przypadku szybsze niż gc?

go wersja: 1.0.2 gcc wersja: 4.7.2

EDIT:

Och, ja zupełnie zapomniałem wspomnieć ... I oczywiście próbował pprof na gccgo -generated binarny. .. Oto 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 

I dlatego szukam czegoś innego.

EDIT2:

Ponieważ wydaje się, że ktoś chce moje pytanie zostać zamknięte, nie próbować używać gprof out of the blue: https://groups.google.com/d/msg/golang-nuts/1xESoT5Xcd0/bpMvxQeJguMJ

+0

Ludzie nadal [* wierzą w gprof jako kanoniczny profiler. *] (Http://stackoverflow.com/a/1779343/23771). Niektóre punkty: 1) gprof jest użyteczny tylko dla programów związanych z CPU z płytkimi stosami wywołań, bez rekursji, dla których ma wszystkie symbole. 2) Optymalizacja kompilatora powoduje tylko różnicę w ciasnych wewnętrznych pętlach lub procedurach nazywanych dużo w kodzie, które same nie wywołują funkcji (jak przydział pamięci itp.). Optymalizacja kompilatora nie tylko sprawia, że ​​wszystko idzie szybciej. –

+0

Tak, mam go dla gprof. I zgadzam się z tobą na temat optymalizacji kompilatora. Jednak nie spodziewałbym się gorszych wydajności z kompilatorem zoptymalizowanym. Występy powinny być równe lub lepsze. Jeśli nie, to jest miejsce na polepszenie i chciałbym zrozumieć dlaczego :) –

+0

Jedyny moment jaki kiedykolwiek zrobiłem to end-to-end, prawdopodobnie powtórzony 10^n razy i podzielony przez to i nie szukam dokładność większa niż 3 cyfry. Jest hałas i mnie to nie obchodzi. Następnie używam losowego wstrzymywania, aby szukać sposobów na przyspieszenie. O ile nie jest już wyciśnięty jak gąbka, znajdę sposoby, a potem będę mógł to wszystko powtórzyć. Kiedy po kilku cyklach odczuwam malejące zyski, a komputer najczęściej pojawia się w generowanych przeze mnie instrukcjach, włączam optymalizator, co może być o 10% szybsze. Whoopee. –

Odpowiedz

2

Running binarny gccgo generowane pod Valgrind wydaje wskazujące, że gccgo ma nieefektywny alokator pamięci. Może to być jeden z powodów, dla których gccgo 4.7.2 jest wolniejszy niż go 1.0.2. Niemożliwe jest uruchomienie binarnego generowanego przez go 1.0.2 pod Valgrind, więc trudno jest potwierdzić fakt, czy alokacja pamięci jest w tym przypadku głównym problemem wydajności gccgo.

+0

Dzięki za wzmianka o "Valgrind". Po raz pierwszy zajmuję się profilowaniem i chociaż gprof jest profilerem ... Myliłem się :) Jednak wygląda na to, że 'Valgrind' jest strukturą profilowania/profilowania opartą tylko na C. Narzeka na niezasocjalizowane wartości i nie wydaje się, że "w ogóle" idzie. Czy mógłbyś trochę rozwinąć? –

+0

Użyłem 'valgrind --tool = callgrind' i KCacheGrind do zbadania zachowania kodu generowanego przez gccgo. Callgrind firmy Valgrind może również uruchamiać wiele kodów innych niż C, ale niestety przyjmuje założenia, które są łamane przez pliki binarne wygenerowane przez go1.0.2. https://code.google.com/p/go/issues/detail?id=782 –

0

Pamiętaj go build także domyślne do łączenia statycznego więc dla jabłek do porównania jabłka należy podać gccgo opcję -static lub -static-libgo.

Powiązane problemy