Clang vs GCC - który produkuje lepsze pliki binarne? [Zamknięte]

238

Obecnie używam GCC, ale niedawno odkryłem Clanga i zastanawiam się nad zmianą. Jest jednak jeden decydujący czynnik - jakość (szybkość, wielkość pamięci, niezawodność) tworzonych plików binarnych - jeśli gcc -O3można wytworzyć plik binarny, który działa 1% szybciej lub zajmuje 1% mniej pamięci, jest to przełom.

Clang może pochwalić się lepszymi prędkościami kompilacji i mniejszą pamięcią czasu kompilacji niż GCC, ale naprawdę interesują mnie testy porównawcze / porównania powstałego skompilowanego oprogramowania - czy możesz wskazać mi jakieś lub opisać swoje doświadczenia?

SF.
źródło
5
Nadal wydaje się cennym pytaniem i odpowiedziami, a wielu jest zainteresowanych.
YasserAsmi
9
@YasserAsmi: A te dwa wskaźniki - ślad pamięci i szybkość wykonania - są dalekie od arbitralności lub podlegają „opinii”. Ale wygląda na to, że rozprzestrzenia się tutaj choroba Physics.SE i ludzie zaczęli głosować na zakończenie, nie czytając tutaj również szczegółów tekstu pytania.
SF.
12
pytanie dotyczy testów porównawczych i porównań, odpowiedź daje oba ... dlaczego ta opinia zamiast faktycznego porównania?
oemb1905
2
Nie rozumiem, dlaczego to pytanie zostało zamknięte. Niezależnie od tego, czy jest to opinia, czy fakt, chcemy poznać odpowiedź, a oznaczenie go jako zamkniętego nadaje mu negatywny odcień, w którym nie powinno go być.
Timothy Makobu,
2
@TomZych: Jeśli chcesz poznać te czynniki, zadaj inne pytania. Ten jest bardzo konkretny i jednoznaczny - pyta o szybkość wykonania i ilość pamięci. Możesz być zainteresowany innymi czynnikami, które są dla ciebie dobre, co nie oznacza, że ​​to pytanie jest nieprawidłowe, po prostu nie spełnia Twoich osobistych zainteresowań. To tak, jakbyś był programistą Java i chce zamknąć każde pytanie w C #, ponieważ nie mówi o Javie.
SF.

Odpowiedzi:

239

Oto kilka aktualnych, choć wąskich ustaleń z GCC 4.7.2 i Clang 3.2 dla C ++.

AKTUALIZACJA: Załączono poniżej porównanie GCC 4.8.1 v clang 3.3.

AKTUALIZACJA: Dołączono do tego porównanie GCC 4.8.2 v clang 3.4.

Utrzymuję narzędzie OSS, które jest zbudowane dla Linuksa z GCC i Clang oraz z kompilatorem Microsoft dla Windows. Narzędzie, coan, jest preprocesorem i analizatorem plików źródłowych C / C ++ i takich linii kodowych: jego profil obliczeniowy specjalizuje się w parsowaniu rekurencyjnym i obsłudze plików. Dział rozwoju (do którego odnoszą się te wyniki) obejmuje obecnie około 11 KB LOC w około 90 plikach. Jest teraz kodowany w C ++, który jest bogaty w polimorfizm i szablony, ale wciąż jest pogrążony w wielu łatach przez swoją nie tak daleką przeszłość w zhakowanych razem C. Semantyka ruchu nie jest wyraźnie wykorzystywana. Jest jednowątkowy. Nie poświęciłem żadnego poważnego wysiłku na jego optymalizację, podczas gdy „architektura” pozostaje w dużej mierze do zrobienia.

Użyłem Clanga przed 3.2 tylko jako eksperymentalny kompilator, ponieważ pomimo doskonałej prędkości kompilacji i diagnostyki, jego obsługa standardu C ++ 11 pozostawała w tyle za współczesną wersją GCC pod względem wykonywanym przez Coana. W wersji 3.2 luka ta została zamknięta.

Moja wiązka testowa systemu Linux do bieżących procesów programistycznych Coan z grubsza 70 000 plików źródłowych w mieszaninie przypadków analizatora składni z jednym plikiem, testy warunków skrajnych zużywa tysiące plików i testy scenariuszy z plikami mniejszymi niż 1 KB. Oprócz raportowania wyników testu, uprząż gromadzi i wyświetla sumy zużytych plików i czasu pracy zużytego w Coan (po prostu przekazuje każdą linię poleceń Coan do timepolecenia Linux i przechwytuje i sumuje zgłoszone liczby). Czasy są pochlebne przez fakt, że dowolna liczba testów, które wymagają 0 mierzalnego czasu, zsumuje się do 0, ale wkład takich testów jest znikomy. Statystyki czasu są wyświetlane na końcu w make checknastępujący sposób:

coan_test_timer: info: coan processed 70844 input_files.
coan_test_timer: info: run time in coan: 16.4 secs.
coan_test_timer: info: Average processing time per input file: 0.000231 secs.

Porównałem wydajność wiązki testowej między GCC 4.7.2 a Clang 3.2, przy czym wszystkie rzeczy były takie same, z wyjątkiem kompilatorów. Począwszy od wersji Clang 3.2, nie wymagam już żadnego preprocesora rozróżnienia między traktami kodu, które GCC będzie kompilować, a alternatywami Clanga. W każdym przypadku zbudowałem tę samą bibliotekę C ++ (GCC) i przeprowadziłem wszystkie porównania kolejno w tej samej sesji terminalowej.

Domyślny poziom optymalizacji dla mojej wersji wydania to -O2. Z powodzeniem testowałem również kompilacje w -O3. Testowałem każdą konfigurację 3 razy jeden po drugim i uśredniłem 3 wyniki, z następującymi wynikami. Liczba w komórce danych to średnia liczba mikrosekund zużywanych przez plik wykonywalny Coana do przetworzenia każdego z plików wejściowych ~ 70K (odczyt, parsowanie i zapisywanie danych wyjściowych oraz diagnostyka).

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 231 | 237 |0.97 |
----------|-----|-----|-----|
Clang-3.2 | 234 | 186 |1.25 |
----------|-----|-----|------
GCC/Clang |0.99 | 1.27|

Każda konkretna aplikacja najprawdopodobniej ma cechy, które działają niesprawiedliwie w stosunku do mocnych i słabych stron kompilatora. Rygorystyczne testy porównawcze wykorzystują różnorodne aplikacje. Mając to na uwadze, godnymi uwagi cechami tych danych są:

  1. Optymalizacja -3 była nieznacznie szkodliwa dla GCC
  2. Optymalizacja O3 była bardzo korzystna dla Clanga
  3. Przy optymalizacji -O2 GCC był szybszy niż Clang tylko dzięki wąsowi
  4. Przy optymalizacji -O3 Clang był znacznie szybszy niż GCC.

Kolejne interesujące porównanie dwóch kompilatorów pojawiło się przypadkiem wkrótce po tych ustaleniach. Coan swobodnie stosuje inteligentne wskaźniki, a jeden z nich jest mocno wyćwiczony w obsłudze plików. Ten konkretny typ inteligentnego wskaźnika został wpisany we wcześniejszych wersjach ze względu na różnicowanie kompilatora, aby był std::unique_ptr<X>skonfigurowany, jeśli skonfigurowany kompilator miał wystarczająco dojrzałe wsparcie dla jego użycia jako takiego, a poza tym std::shared_ptr<X>. Odchylenie std::unique_ptrbyło głupie, ponieważ wskaźniki te faktycznie zostały przeniesione, ale std::unique_ptrwyglądały jak opcja montera do zastąpienia std::auto_ptrw momencie, gdy warianty C ++ 11 były dla mnie nowością.

W trakcie eksperymentalnych kompilacji w celu oceny ciągłej potrzeby tego i podobnego różnicowania w Clang 3.2, nieumyślnie zbudowałem, std::shared_ptr<X>gdy miałem zamiar budować std::unique_ptr<X>, i byłem zaskoczony, że wynikowy plik wykonywalny, z domyślną optymalizacją -O2, był najszybszy I widziałem, czasem osiągając 184 msek. na plik wejściowy. Przy tej jednej zmianie w kodzie źródłowym były to odpowiednie wyniki;

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 234 | 234 |1.00 |
----------|-----|-----|-----|
Clang-3.2 | 188 | 187 |1.00 |
----------|-----|-----|------
GCC/Clang |1.24 |1.25 |

Ważnymi punktami tutaj są:

  1. Żaden kompilator nie korzysta teraz w ogóle z optymalizacji -O3.
  2. Clang pokonuje GCC równie ważne na każdym poziomie optymalizacji.
  3. Na wydajność GCC jedynie nieznaczny wpływ ma zmiana typu inteligentnego wskaźnika.
  4. Na wydajność Clanga -O2 istotny wpływ ma zmiana typu inteligentnego wskaźnika.

Przed i po zmianie typu inteligentnego wskaźnika Clang jest w stanie zbudować znacznie szybszy plik wykonywalny Coana przy optymalizacji -O3 i może zbudować równie szybszy plik wykonywalny przy -O2 i -O3, gdy ten typ wskaźnika jest najlepszy - std::shared_ptr<X>- dla pracy.

Oczywistym pytaniem, którego nie jestem kompetentny do skomentowania, jest to, dlaczego Clang powinien być w stanie znaleźć przyspieszenie o 25% O2 w mojej aplikacji, gdy często używany typ inteligentnego wskaźnika zmienia się z unikalnego na współdzielony, podczas gdy GCC jest obojętny do tej samej zmiany. Nie wiem też, czy powinienem kibicować, czy wygłupiać się odkryciem, że optymalizacja Clang -O2 kryje w sobie tak ogromną wrażliwość na mądrość moich mądrych wskazówek.

AKTUALIZACJA: GCC 4.8.1 v clang 3.3

Odpowiednie wyniki są teraz:

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.1 | 442 | 443 |1.00 |
----------|-----|-----|-----|
Clang-3.3 | 374 | 370 |1.01 |
----------|-----|-----|------
GCC/Clang |1.18 |1.20 |

Fakt, że wszystkie cztery pliki wykonywalne zajmują teraz znacznie więcej czasu niż poprzednio, aby przetworzyć 1 plik, nie ma wpływu na wydajność najnowszych kompilatorów. Wynika to z faktu, że późniejsza gałąź programistyczna aplikacji testowej nabrała w międzyczasie wielu parsowania i szybko za to płaci. Istotne są tylko stosunki.

Najważniejsze kwestie nie są teraz zaskakująco nowe:

  • GCC jest obojętny na optymalizację -O3
  • clang korzysta bardzo nieznacznie z optymalizacji -O3
  • clang pokonuje GCC o podobnie ważny margines na każdym poziomie optymalizacji.

Porównując te wyniki z wynikami dla GCC 4.7.2 i clang 3.2, wyróżnia się, że GCC cofnęło około jednej czwartej przewagi clanga na każdym poziomie optymalizacji. Ponieważ jednak aplikacja testowa została w międzyczasie bardzo rozbudowana, nie można tego z pewnością przypisać do nadrabiania zaległości w generowaniu kodu GCC. (Tym razem zauważyłem migawkę aplikacji, z której uzyskano taktowanie i mogę z niej ponownie korzystać.)

AKTUALIZACJA: GCC 4.8.2 v clang 3.4

Ukończyłem aktualizację dla GCC 4.8.1 v Clang 3.3, mówiąc, że będę trzymał się tej samej migawki Coan w celu dalszych aktualizacji. Ale zamiast tego zdecydowałem się przetestować tę migawkę (wersja 301) i najnowszą migawkę programistyczną, która przeszła pomyślnie przez zestaw testów (wersja 619). To daje trochę długości geograficznej, a miałem inny motyw:

W moim pierwotnym poście zauważyłem, że nie poświęciłem żadnego wysiłku na optymalizację coana pod kątem szybkości. Tak było nadal od wersji rev. 301. Jednak po tym, jak wbudowałem przyrząd do pomiaru czasu w uprząż testową Coana, za każdym razem, gdy uruchamiałem zestaw testowy, wpatrywał się we mnie wpływ najnowszych zmian na wydajność. Widziałem, że często był on zaskakująco duży i że trend był bardziej negatywny, niż czułem, że zasługują na mnie korzyści z funkcjonalności.

Przez rev. 308 średni czas przetwarzania na plik wejściowy w pakiecie testowym znacznie wzrósł ponad dwukrotnie od czasu pierwszego opublikowania tutaj. W tym momencie dokonałem zwrotu w mojej 10-letniej polityce nie zawracania sobie głowy wydajnością. W intensywnym szeregu zmian zawsze brano pod uwagę wydajność do 619, a duża liczba z nich poszła wyłącznie na przepisanie kluczowych nośników na zasadniczo szybszych liniach (choć bez użycia do tego żadnych niestandardowych funkcji kompilatora). Byłoby ciekawie zobaczyć reakcję każdego kompilatora na ten zwrot,

Oto znana już macierz czasowa dla najnowszych dwóch kompilatorów kompilacji rev.301:

coan - rev.301 wyniki

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 428 | 428 |1.00 |
----------|-----|-----|-----|
Clang-3.4 | 390 | 365 |1.07 |
----------|-----|-----|------
GCC/Clang | 1.1 | 1.17|

Historia tutaj jest tylko nieznacznie zmieniona z GCC-4.8.1 i Clang-3.3. Pokazywanie GCC jest trochę lepsze. Clang's jest trochę gorszy. Hałas mógłby to wyjaśnić. Clang wciąż wychodzi przed siebie -O2i -O3marże, które nie miałyby znaczenia w większości aplikacji, ale miałyby znaczenie dla kilku.

A oto macierz dla rev. 619.

coan - rev.619 wyników

          | -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 210 | 208 |1.01 |
----------|-----|-----|-----|
Clang-3.4 | 252 | 250 |1.01 |
----------|-----|-----|------
GCC/Clang |0.83 | 0.83|

Biorąc obok siebie cyfry 301 i 619, wypowiada się kilka punktów.

  • Chciałem napisać szybszy kod, a oba kompilatory zdecydowanie potwierdzają moje wysiłki. Ale:

  • GCC spłaca te wysiłki o wiele hojniej niż Clang. Przy -O2 optymalizacji Clang 619 kompilacji jest 46% szybszy niż 301 kompilacji: przy -O3poprawie Clanga wynosi 31%. Dobrze, ale na każdym poziomie optymalizacji wersja 619 GCC jest ponad dwa razy szybsza niż 301.

  • GCC bardziej niż odwraca dawną wyższość Clanga. Na każdym poziomie optymalizacji GCC bije teraz Clanga o 17%.

  • Zdolność Clanga w kompilacji 301 do uzyskania większej dźwigni niż GCC z -O3optymalizacji zniknęła w kompilacji 619. Żaden kompilator nie zyskuje znacząco -O3.

Byłem wystarczająco zaskoczony tym odwróceniem losu, że podejrzewałem, że mógłbym przypadkowo stworzyć powolną kompilację samego klangu 3.4 (ponieważ zbudowałem go ze źródła). Więc ponownie przeprowadziłem test 619 z zapasem mojej dystrybucji Clang 3.3. Wyniki były praktycznie takie same jak dla 3.4.

Jeśli chodzi o reakcję na zawrót: pod tym względem Clang radził sobie znacznie lepiej niż GCC z szybkością wyciskania z mojego kodu C ++, kiedy nie dawałem mu żadnej pomocy. Kiedy postanowiłem pomóc, GCC wykonało znacznie lepszą robotę niż Clang.

Nie podniosę tej obserwacji do zasady, ale czerpię naukę, że „Który kompilator produkuje lepsze pliki binarne?” jest pytaniem, które nawet jeśli określisz zestaw testów, dla którego odpowiedź powinna być względna, nadal nie jest jednoznaczną kwestią po prostu określania czasu plików binarnych.

Czy Twój lepszy plik binarny jest najszybszym plikiem binarnym, czy to ten, który najlepiej rekompensuje tanio spreparowany kod? A może najlepiej rekompensuje drogo spreparowany kod, który priorytetem jest łatwość konserwacji i ponowne wykorzystanie nad prędkością? Zależy to od charakteru i względnej wagi motywów tworzenia pliku binarnego oraz ograniczeń, na podstawie których to robisz.

W każdym razie, jeśli bardzo zależy ci na budowaniu „najlepszych” plików binarnych, lepiej sprawdzaj, w jaki sposób kolejne iteracje kompilatorów dostarczają ideę „najlepszej” nad kolejnymi iteracjami twojego kodu.

Mike Kinghan
źródło
9
dlaczego brzęczy szybciej? na przykład kompilator Intel używał specjalizacji układów scalonych Intel. z czego korzysta clang, aby uzyskać przewagę? czy można przepisać kod, aby gcc miał taką samą wydajność?
kirill_igum
27
@krill_igum GCC i clang są różnymi (niezwykle złożonymi) programami napisanymi przez różne grupy programistów do wykonania tego samego zadania: przetłumacz kod źródłowy na kod obiektowy. Jest prawie nieuniknione, że jeden z nich wykona tę pracę znacznie lepiej niż drugi w dowolnym wybranym teście w dowolnym momencie. Nie musi być żadnej specjalnej „rzeczy”, którą zwycięzca „wykorzystuje”, aby „uzyskać przewagę”, a ponieważ oba programy są open source, nie mają przed sobą żadnych tajemnic.
Mike Kinghan
3
Można użyć kcachegrinddo wskazania funkcji, w których generowane pliki wykonywalne różnią się wydajnością.
4
-1: To bardziej powieść (lub post na blogu) niż odpowiedź.
John Saunders
60
@JohnSaunders: To, co dla jednej osoby jest szczegółową, dogłębną odpowiedzią, dla innej jest powieścią niegodną ich uwagi. Powiedz mi, co wyróżnia te dwie osoby.
SF.
48

Phoronix przeprowadził kilka testów w tym zakresie, ale chodzi o migawkową wersję Clang / LLVM sprzed kilku miesięcy. Rezultat jest taki, że rzeczy były mniej więcej popychaniem; ani GCC, ani Clang nie są zdecydowanie lepsze we wszystkich przypadkach.

Ponieważ użyjesz najnowszego Clanga, może to trochę mniej istotne. Z drugiej strony, GCC 4.6 prawdopodobnie ma kilka istotnych optymalizacji dla Core 2 i i7.

Myślę, że szybsza prędkość kompilacji Clanga będzie lepsza dla oryginalnych programistów, a następnie, gdy wypchniesz kod na świat, dystrybucja Linux / BSD / itp. użytkownicy końcowi będą używać GCC do szybszych plików binarnych.

Nietzche-jou
źródło
2
Właśnie dzisiaj uruchomiłem kilka testów porównawczych dotyczących prędkości kompilacji Clanga i jest to bardzo rozczarowujące dla czystego C. Kompilowanie plików 35 C z 270 KLOC clang było tylko o 25% szybsze. Kiedy widzę, jak szybki jest Tinycc na Linuksie, jest to zły wynik dla nowego napisanego kompilatora. Poprawia się przy korzystaniu z optymalizacji -O2 / -O3, ale ponieważ są one używane do kompilacji wersji, wydajność kompilatora nie ma znaczenia w takich przypadkach.
Lothar,
7
@mcandre Może Nietzche-jou został skompilowany z Clangiem, podczas gdy ty byłeś skompilowany z GCC.
Mateen Ulhaq,
18

Fakt, że Clang kompiluje kod szybciej, może nie być tak ważny jak szybkość wynikowego pliku binarnego. Oto jednak seria testów porównawczych .

Mcandre
źródło
12
Właściwie to robi. Podczas opracowywania czas kompilacji (i zużycie zasobów z powodu kompilacji) są znacznie bardziej wąskim gardłem niż wydajność binarna. W końcu na tym etapie kompilujemy w trybie debugowania. Tylko wtedy, gdy nadchodzi etap testowania i wysyłki, przełączasz się w tryb Release i starasz się uzyskać jak najszybciej plik binarny.
Matthieu M.
3
@ Matthieu M: Przysięgam, że odpowiedź brzmiała „może ..”, jakby budził potencjalne obawy. Chyba warto było o tym wspomnieć, bo to było związane z PO.
JM Becker,
Zgadzam się, chociaż tutaj wszystkie dobre punkty. Wolę wrzucić drugi lub trzeci dysk RAID 0, dysk SSD lub więcej i szybszą pamięć RAM i uzyskać najlepszą wydajność .exe - pod warunkiem, że te środki mogą doprowadzić do parzystości lub zamknięcia. Czasami pomocne jest rozwijanie z więcej niż jednym kompilatorem. Może uświadomić ci nieprzenośne funkcje ORAZ wykryć błędy, które w przeciwnym razie pozostałyby niewykryte lub prowadzić do dni marnowania czasu na próby debugowania kodu, na który ostrzegałby / kompilowałby się lepszy kompilator.
Próbowałem dzisiaj, porównując napisany przeze mnie kod liczb całkowitych o znaczeniu krytycznym, a GCC działał znacznie szybciej (22S clang-llvm 25S), używając zarówno -O2, jak i -O3. Pomyśl, że użycie przełączników kompilatora (gcc lub clang) obejmuje większość niestandardowych funkcji i ostrzeżeń statycznych. W swoim własnym dużym projekcie, nie kompilując wsadowo kodu innego ppl, robisz coś złego w systemie kompilacji, jeśli czas kompilacji dominuje nad czasem łącza. Istnieją narzędzia takie jak ccache.samba.org, które pomagają, jeśli często czyścisz . Kolejnym problemem związanym ze zmianą kompilatorów jest wyrzucanie inwestycji w testowanie / sprawdzanie poprawności.
Rob11311,
code.google.com/p/distcc to kolejny projekt, który może przyspieszyć czas kompilacji zbiorczej, jeśli cała biblioteka wymaga ponownej kompilacji ze względu na zmiany struktury danych lub do celów weryfikacji / weryfikacji
Rob11311
11

Jest bardzo mała ogólna różnica między GCC 4.8 a clang 3.3 pod względem szybkości wynikowego pliku binarnego. W większości przypadków kod wygenerowany przez oba kompilatory działa podobnie. Żaden z tych dwóch kompilatorów nie dominuje nad drugim.

Benchmarki stwierdzające, że istnieje znaczna różnica w wydajności między GCC a klangiem, są przypadkowe.

Wybór kompilatora zależy od wydajności programu. Jeśli programista lub grupa programistów korzysta wyłącznie z GCC, można oczekiwać, że program będzie działał nieco szybciej z GCC niż z clang i odwrotnie.

Z punktu widzenia programisty zauważalna różnica między GCC 4.8+ a clang 3.3 polega na tym, że GCC ma -Ogopcję wiersza poleceń. Ta opcja umożliwia optymalizacje, które nie zakłócają debugowania, więc na przykład zawsze można uzyskać dokładne ślady stosu. Brak tej opcji w clang sprawia, że ​​trudniej jest używać clang jako kompilatora optymalizującego dla niektórych programistów.


źródło
Ostatnio (3.3 i 4.8) nie widzę nawet dużej różnicy między czasem kompilacji. (w „moich” programach z czasami kompilacji od 10 sekund do 30 sekund).
alfC
9

Jedynym sposobem na określenie tego jest wypróbowanie. FWIW Widziałem kilka naprawdę dobrych ulepszeń przy użyciu Apple LLVM gcc 4.2 w porównaniu ze zwykłym gcc 4.2 (dla kodu x86-64 z dość dużą ilością SSE), ale YMMV dla różnych baz kodu. Zakładając, że pracujesz z x86 / x86-64 i że naprawdę zależy ci na ostatnich kilku procentach, powinieneś również wypróbować ICC Intela, ponieważ często może to pobić gcc - możesz uzyskać 30-dniową licencję próbną z intel.com i spróbuj.

Paul R.
źródło
8

Szczególną różnicą, którą zauważyłem w gcc 5.2.1 i clang 3.6.2, jest to, że jeśli masz krytyczną pętlę, taką jak:

for (;;) {
    if (!visited) {
        ....
    }
    node++;
    if (!*node) break;
  }

Następnie gcc podczas kompilacji z -O3lub -O2spekulacyjnie rozwija pętlę osiem razy. Clang w ogóle go nie rozwinie. Dzięki próbom i błędom odkryłem, że w moim konkretnym przypadku z danymi mojego programu odpowiednia ilość rozwijania wynosi pięć, więc gcc jest przekroczony i kliknął poniżej. Przekroczenie było jednak bardziej szkodliwe dla wyników, więc gcc działał tutaj znacznie gorzej.

Nie mam pojęcia, czy różnica w rozwijaniu jest ogólnym trendem, czy tylko czymś specyficznym dla mojego scenariusza.

Jakiś czas temu napisałem kilka śmieciarek, aby nauczyć się więcej na temat optymalizacji wydajności w C. A wyniki, które uzyskałem, są w mojej głowie na tyle, aby lekko sprzyjać brzęczeniu. Zwłaszcza, że ​​odśmiecanie polega głównie na ściganiu wskaźnika i kopiowaniu pamięci.

Wyniki są następujące (liczby w sekundach):

+---------------------+-----+-----+
|Type                 |GCC  |Clang|
+---------------------+-----+-----+
|Copying GC           |22.46|22.55|
|Copying GC, optimized|22.01|20.22|
|Mark & Sweep         | 8.72| 8.38|
|Ref Counting/Cycles  |15.14|14.49|
|Ref Counting/Plain   | 9.94| 9.32|
+---------------------+-----+-----+

To wszystko jest czystym kodem C i nie twierdzę, że którykolwiek z kompilatorów działa podczas kompilowania kodu C ++.

Na Ubuntu 15.10, x86.64 i procesor AMD Phenom (tm) II X6 1090T.

Björn Lindqvist
źródło
4

Zasadniczo odpowiedź brzmi: to zależy. Istnieje wiele wielu testów porównawczych dotyczących różnych rodzajów aplikacji.

Mój test porównawczy w mojej aplikacji to: gcc> icc> clang.

Istnieją rzadkie operacje wejścia / wyjścia, ale wiele operacji zmiennoprzecinkowych i operacji na strukturze danych.

flagi kompilacji to -Wall -g -DNDEBUG -O3.

https://github.com/zhangyafeikimi/ml-pack/blob/master/gbdt/profile/benchmark

kimi
źródło