GCC vs. Clang/LLVM: An In-Depth Comparison of C/C++ Compilers

Visual C++, GNU Compiler Collection (GCC), and Clang/Low Level Virtual Machine (LLVM) are three mainstream C/C++ compilers in the industry. Visual C++ oferă interfețe grafice de utilizator (GUI) și este ușor de depanat, dar nu este potrivit pentru platformele Linux. Prin urmare, acest document compară în principal GCC cu Clang/LLVM.

GCC este un compilator de limbaj de program dezvoltat de GNU. Este un set de software liber lansat sub GNU General Public License (GPL) și GNU Lesser General Public License (LGPL). Este un compilator oficial pentru sistemele GNU și Linux și un compilator principal pentru compilarea și crearea altor sisteme de operare UNIX.

LLVM conține o serie de componente compilatoare modularizate și lanțuri de scule. Se poate optimiza limbaje de program și link-uri în timpul compilării, runtime, și inactiv timp și de a genera cod. LLVM poate servi ca fundal pentru compilatoare în mai multe limbi. Clang este un compilator C, C++, Objective-C sau Objective-C++ care este compilat în c++ bazat pe LLVM și lansat sub licența Apache 2.0. Clang este utilizat în principal pentru a oferi performanțe superioare celei a GCC.

prin dezvoltarea și iterația pe termen lung, GCC, zăngănit și LLVM au devenit compilatoare mature în industrie. Atunci, care compilator este mai bun? Pe care ar trebui să le folosim pentru a compila și construi programe și sisteme?

semnificația unui compilator bun

procesoarele moderne au toate conducte superscalare și lungi și structuri interne complexe și acceptă unități de extensie vectorială în Complex computer set de instrucțiuni (CISC) sau Computer set de instrucțiuni redus (RISC) arhitectură. Pentru multe programe care conțin kerneluri generale intensive în calcul, programatorii pot utiliza comenzi de extensie vectorială pentru a îmbunătăți considerabil performanța de execuție a programului. De exemplu, în operațiile matrice și vectoriale, comenzile combinate de multiplicare și adăugare sunt utilizate pentru a îmbunătăți performanța și precizia. Comenzile Bit mask sunt utilizate pentru procesarea ramurilor în operații vectoriale. Cu toate acestea, pentru a obține cele mai înalte performanțe, programatorii și compilatorii trebuie să depună mult efort pentru a gestiona sarcini cu moduri complexe de acces la memorie și kerneluri non-standard.

în plus, standardele limbajelor avansate moderne abstractizează constant detaliile hardware-ului și structurilor de date subiacente pentru a genera cod general mai logic și matematic, în loc de instrucțiuni de operare specifice și căi de acces la memorie. Standardele C++ sunt din ce în ce mai expresive și abstracte. Python este popular deoarece este mai lizibil și mai expresiv, chiar și cu prețul unei viteze de rulare mai mici. Expresivitatea mai mare crește povara compilatorului pentru a genera un cod de asamblare bun din structurile complexe compilate de programatori. Compilatorul trebuie să fie mai inteligent și să lucreze mai mult pentru a maximiza performanța utilizând codul. Nu toți compilatorii pot face acest lucru. Când selectăm un compilator, trebuie să analizăm mai întâi dacă același segment de cod poate genera comenzi de asamblare mai eficiente.

pe lângă generarea de programe executabile de înaltă performanță, compilatoarele moderne trebuie să aibă și ele performanțe ridicate. Un proiect software de dimensiuni mari în C++ poate conține sute până la mii de unități individuale de traducere. Fiecare unitate de traducere poate conține mii de linii de cod. Codul C++ poate utiliza, de asemenea, un număr mare de tehnologii de programare bazate pe șabloane. Aceste tehnologii necesită compilatorul să transfere informații relevante de mai multe ori pentru a genera un fișier țintă. Compilarea proiectelor C++ de dimensiuni mari poate dura câteva ore, iar mai multe modificări dependente reciproc trebuie depuse concomitent în timpul dezvoltării. Fiecare depunere cere dezvoltatorilor să recompileze majoritatea bibliotecilor de cod. Prin urmare, compilatoarele mai rapide (instrumente de construire) sunt esențiale pentru obținerea unei productivități ridicate pentru echipele mari.în ceea ce privește extinderea limbajului, sistemele moderne de calcul cu mai multe nuclee, capabilități de procesare vectorială și acceleratoare oferă capabilități superioare capacităților naturale ale limbajelor de programare comune. Prin urmare, cadrele specifice de calcul de înaltă performanță (HPC), cum ar fi OpenMP și OpenACC, pot umple acest gol. Aceste cadre oferă interfețe de program de aplicație (API-uri) pe care programatorii le pot folosi pentru a exprima paralelismul în cod. Compilatorul și biblioteca de execuție corespunzătoare trebuie să mapeze codul paralel cu arhitectura procesorului. Multe proiecte HPC depind de standardele OpenMP și OpenACC, care sunt extinse de dezvoltatori și producători de hardware. Prin urmare, compilatorii trebuie să țină pasul cu dezvoltarea standardelor de extindere a limbajului.

În concluzie, un compilator bun ne permite să ne concentrăm asupra procesului de programare, mai degrabă decât să luptăm împotriva neajunsurilor sale. Poate suporta cele mai recente standarde lingvistice, poate genera comenzi optimizate din cel mai abstract cod și poate compila codul sursă în mai puțin timp.

istoricul dezvoltării CCG

înainte de a învăța CCG, trebuie să înțelegeți mai întâi proiectul GNU. Richard Stallman a lansat proiectul GNU în 1984 pentru a construi un sistem software open source asemănător UNIX. Sistemul de operare GNU nu a evoluat extensiv de-a lungul timpului. Cu toate acestea, a incubat multe instrumente software excelente și utile open source, cum ar fi Make, sed, Emacs, Glibc, GDB și GCC. Aceste software-uri GNU open source și nucleele Linux constituie împreună sistemul GNU/Linux. La început, GCC a furnizat compilatoare stabile și fiabile, bazate pe limbajul de programare C, pentru sistemul GNU. Numele său complet este GNU C Compiler. Mai târziu, au fost acceptate mai multe limbi (cum ar fi Fortran, Obj-C și Ada), iar numele complet al GCC s-a schimbat în GNU Compiler Collection.GCC-1.0 a fost lansat de Richard Stallman în 1987, acum mai bine de treizeci de ani. Din punct de vedere software-ul este foarte vechi. Cineva a colectat înregistrările de dezvoltare GCC între 1989 și 2012 și a produs un videoclip animat de treizeci de minute (GNU Compiler Collection dev history 1989-2012), demonstrând intuitiv procesul de dezvoltare al GCC. Putem afla despre istoria dezvoltării GCC din versiunile sale:

  • GCC-1.0: lansat de Richard Stallman în 1987.
  • GCC-2.0: Lansat în 1992 și acceptat c++. Mai târziu, comunitatea GCC a fost împărțită deoarece Richard Stallman a definit GCC ca un compilator C fiabil al sistemului GNU și a crezut că GCC la acel moment era suficient pentru sistemul GNU și accentul de dezvoltare ar trebui mutat de la GCC la sistemul GNU în sine. Alți dezvoltatori majori au sperat să continue îmbunătățirea CCG și să facă evoluții și îmbunătățiri mai radicale în diferite aspecte. Acești dezvoltatori activi au părăsit comunitatea GCC în 1997 și au dezvoltat furca EGCS.
  • GCC-3.0: evident, dezvoltatorii au avut, în general, o dorință puternică de compilatoare bune. Furca EGCS s-a dezvoltat fără probleme și a devenit recunoscută de tot mai mulți dezvoltatori. În cele din urmă, EGCS a fost folosit ca nou coloana vertebrală GCC și GCC-3.0 a fost lansat în 2001. Comunitatea divizată a fost Re-fuzionată din nou, dar influența lui Richard Stallman a fost slăbită într-o anumită măsură. În plus, Comitetul industrial al CCG a început să decidă direcția de dezvoltare a CCG.
  • GCC-4.0: lansat în 2005. Această versiune a fost integrată în Tree Serial Storage Architecture (ssa), iar GCC a evoluat pentru a fi un compilator modern.
  • GCC-5.0: lansat în 2015. Ulterior, Politica versiunii GCC a fost ajustată și o versiune majoră a fost lansată în fiecare an. Un beneficiu neașteptat este că numărul versiunii corespunde anului. De exemplu, GCC-7 a fost lansat în 2017, iar GCC-9 a fost lansat în 2019.

Acum, dezvoltarea CCG a intrat în „cronica modernă”. Confruntându-se cu presiunea concurențială a LLVM, comunitatea CCG a făcut în mod activ multe ajustări, cum ar fi accelerarea compilării și îmbunătățirea informațiilor de avertizare a compilării. În ultimii 30 de ani, GCC a evoluat de la un provocator în industria compilatoarelor la un compilator principal pentru sistemele Linux, iar acum se confruntă cu provocarea LLVM. Din fericire, comunitatea CCG face ajustări pentru a accelera dezvoltarea CCG. Ne putem aștepta ca concurența dintre cele două tehnologii de compilare să continue să ofere dezvoltatorilor de software compilatoare mai bune.

istoria de dezvoltare a zăngănit și LLVM

LLVM a fost provenit de la cercetarea de Chris Lattner pe UUIC în 2000. Chris Lattner a dorit să creeze o tehnologie de compilare dinamică pentru toate limbile statice și dinamice. LLVM este un tip de software open source dezvoltat sub licența BSD. Versiunea inițială 1.0 a fost lansată în 2003. În 2005, Apple Inc. l-a angajat pe Chris Lattner și echipa sa să dezvolte limbaje de programare și compilatoare pentru computerele Apple, după care dezvoltarea LLVM a intrat pe banda rapidă. Pornind de la LLVM 2.5, două versiuni minore LLVM au fost lansate în fiecare an (în general în martie și septembrie). În noiembrie 2011, LLVM 3.0 a fost lansat pentru a deveni compilatorul Xcode implicit. XCode 5 a început să utilizeze Clang și LLVM 5.0 în mod implicit. Politica versiunii a fost ajustată pentru LLVM 5.0 și versiunile ulterioare, iar două versiuni majore sunt lansate în fiecare an. Versiunea actuală stabilă este 8.0.

numele LLVM a fost prescurtat pentru prima dată de la mașină virtuală de nivel scăzut. Deoarece acest proiect nu se limitează la crearea unei mașini virtuale, abrevierea LLVM este adesea pusă la îndoială. După ce LLVM a fost dezvoltat, a devenit un termen colectiv pentru multe instrumente de compilare și tehnologii de instrumente de nivel scăzut, făcând numele mai puțin adecvat. Dezvoltatorii au decis să renunțe la semnificația din spatele acestei abrevieri. Acum LLVM a devenit numele oficial al mărcii, aplicabil tuturor proiectelor din cadrul LLVM, inclusiv LLVM Intermediate Representation (LLVM IR), LLVM debugging tools și LLVM c++ standard libraries. LLVM poate fi folosit ca compilator tradițional, compilator JIT, asamblor, depanator, instrument de analiză statică și pentru alte funcții legate de limbajele de programare.

în 2012, LLVM a câștigat software system award of Association for Computing Machinery (ACM), împreună cu sisteme tradiționale precum UNIX, WWW, TCP / IP, TeX și Java. LLVM simplifică foarte mult implementarea noilor lanțuri de instrumente de limbaj de programare. În ultimii ani, multe limbaje de programare noi, cum ar fi Swift, Rust și Julia, au folosit LLVM ca cadru de compilare. În plus, LLVM a devenit compilatorul implicit pentru sistemele Mac OS X, iOS, FreeBSD și Android.

zăngăni

zăngăni este proiectat pentru a oferi un compilator frontend care poate înlocui GCC. Apple Inc. (inclusiv următorul mai târziu) a folosit GCC ca compilator Oficial. GCC a funcționat întotdeauna bine ca un compilator standard în comunitatea open source. Cu Toate Acestea, Apple Inc. are propriile cerințe pentru instrumentele de compilare. Pe de o parte, Apple Inc. adăugat multe caracteristici noi pentru limba Objective – C (sau chiar, mai târziu, limba C). Cu toate acestea, dezvoltatorii GCC nu au acceptat aceste caracteristici și au acordat prioritate redusă suportului pentru aceste caracteristici. Mai târziu, acestea au fost pur și simplu împărțite în două ramuri pentru dezvoltare separată și, în consecință, versiunea GCC lansată de Apple Inc. este mult mai devreme decât versiunea oficială. Pe de altă parte, codul GCC este foarte cuplat și greu de dezvoltat separat. În plus, în versiunile ulterioare, calitatea codului continuă să scadă. Cu toate acestea, multe funcții cerute de Apple Inc. (cum ar fi îmbunătățirea mediului de dezvoltare integrat (IDE) suport) trebuie să apeleze GCC ca un modul, dar GCC nu oferă un astfel de sprijin. Mai mult decât atât, scutirea GCC Runtime Library limitează fundamental dezvoltarea LLVM GCC. De asemenea, limitată de licență, Apple Inc. nu se poate utiliza LLVM pentru a îmbunătăți în continuare calitatea generării de cod pe baza GCC. Prin Urmare, Apple Inc. a decis să scrie zăngănit frontend de C, C++, și limbi Objective-C de la zero pentru a înlocui complet GCC.

după cum sugerează și numele, Clang acceptă doar C, C++ și Objective-C. dezvoltarea a început în 2007 și compilatorul C a fost finalizat pentru prima dată. Zăngăni pentru Objective-C cloud fi utilizat pe deplin pentru mediul de producție în 2009. Suportul pentru C++ a progresat rapid. Clang 3.3 a acceptat pe deplin C++ 11, Clang 3.4 a acceptat pe deplin C++ 14 și Clang 5 a acceptat pe deplin C++ 17 și toate au fost semnificativ înaintea GCC la acel moment.

Clang/LLVM și comunitatea GCC

ca și alte comunități de software open source, comunitatea GCC este dominată de entuziaști de software liber și hackeri. În procesul de dezvoltare, mecanismele de gestionare și participare a comunității CCG se formează treptat astăzi. În prezent, comunitatea CCG este o societate de cunoștințe relativ stabilă și bine definită în care fiecare persoană are roluri și îndatoriri clare:

  • Richard Stallman și Free Software Foundation (FSF): deși rareori implicați în managementul comunității CCG, Richard Stallman și FSF sunt încă detașați în afaceri de licență și juridice.
  • Comitetul industrial CCG: Gestionează afacerile comunității GCC, subiectele de dezvoltare GCC independente de tehnologie și numirea și anunțarea recenzorilor și întreținătorilor. În prezent are 13 membri.
  • responsabilii globali: ei domină activitățile de dezvoltare a CCG. Într-o oarecare măsură, ele determină tendința de dezvoltare a CCG. În prezent, există 13 întreținători globali, care nu dețin toți funcții în Comitetul industrial GCC.
  • întreținători Frontend, middle-end și backend: sunt întreținătorii frontend, backend și alte module. Aceștia sunt responsabili pentru codul modulului GCC corespunzător, iar mulți dintre ei sunt principalii contribuitori la codul modulului. Este demn de remarcat faptul că recenzorii sunt în general clasificați în acest grup. Diferența este că recenzenții nu își pot aproba propriul patch, în timp ce întreținătorii își pot prezenta propriile modificări în sfera lor de responsabilitate fără aprobarea recenzenților.
  • contribuitori: sunt cele mai extinse grupuri de dezvoltatori din comunitatea CCG. După semnarea Acordului privind drepturile de autor, orice Dezvoltatori pot solicita permisiunea de scriere după aprobare din partea comunității și apoi pot trimite codul de la sine.

ca și alte comunități open source, comunitatea GCC matură nu mai este dominată de hackeri. Companiile comerciale au început să joace roluri importante în comunitate, cum ar fi recrutarea dezvoltatorilor și sponsorizarea întâlnirilor de dezvoltare. În prezent, comunitatea CCG este dominată de următoarele tipuri de societăți comerciale:

  • furnizori de sistem, în principal, inclusiv RedHat și SUSE.
  • furnizori de cipuri, inclusiv în principal Intel, ARM, AMD și IBM (PowerPC).
  • furnizori specializați, cum ar fi furnizorii de servicii CodeSourcery și tool chain, cum ar fi AdaCore, pe baza limbii Ada. CodeSourcery a avut o istorie strălucitoare și a recrutat mulți dezvoltatori celebri, dar a refuzat după ce a fost achiziționat de Mentor.

în comunitatea actuală GCC, vânzătorii de cipuri domină dezvoltarea backend, în timp ce furnizorii de sisteme ghidează alte domenii de dezvoltare. În ceea ce privește dezvoltarea comunității, codul GCC este găzduit în prezent pe propriul server SVN. Un API Git este furnizat pentru a facilita dezvoltarea și depunerea. Revizuirea corecțiilor este similară cu cea din comunitatea Kernel-ului Linux și folosește formularul listei de corespondență. După cum sa menționat mai sus, comunitatea CCG este o societate relativ stabilă (sau închisă). Comunitatea are practic 150 până la 200 de contribuabili activi în fiecare an și organizează o conferință pentru dezvoltatori în septembrie în fiecare an. În septembrie 2019, Conferința pentru dezvoltatori va avea loc la Montreal, Canada.

comunitatea LLVM

comunitatea LLVM este o comunitate compilator noob-friendly. Acesta răspunde rapid la întrebările noilor utilizatori și recenzii de patch-uri. Aceasta este, de asemenea, baza și sursa pentru discuțiile ulterioare ale Fundației LLVM și adoptarea Codului de conduită comunitar LLVM și provoacă o serie de discuții corecte din punct de vedere politic.

toate proiectele și problemele LLVM sunt discutate prin lista de e-mailuri DevExpress, iar trimiterea codului este notificată prin lista de e-mailuri commits. Toate bug – uri și modificări ale caracteristicilor sunt urmărite prin lista de bug-uri. Patch-urile trimise sunt recomandate pentru ramurile principale. Stilul respectă standardele de codificare LLVM și revizuirea codului se realizează prin Phabricator. În prezent, depozitul de cod LLVM a fost migrat la GitHub.spre deosebire de comunitatea CCG, comunitatea LLVM are doar fundația LLVM. Fundația LLVM are opt membri. Pe lângă gestionarea afacerilor comunitare LLVM, fiecare membru al Fundației LLVM trebuie să ghideze problemele de dezvoltare LLVM legate de tehnologie. În prezent, președintele este Tanya Lattner, soția lui Chris Lattner. Chris Lattner însuși este, de asemenea, membru al fundației și are un control puternic asupra comunității LLVM și a direcției de dezvoltare a LLVM.

Politica de revizuire a codului în comunitatea LLVM este practic aceeași cu cea din comunitatea GCC. Diferența este că, datorită dezvoltării rapide a LLVM, mulți contribuitori nu au permisiunea de acces commit și trebuie să-și prezinte codul prin intermediul întreținătorilor. În prezent, comunitățile zăngănit și LLVM au mai mult de 1.000 de contribuabili în fiecare an. În general, conferințele pentru dezvoltatori se desfășoară anual în aprilie și octombrie. Conferința pentru dezvoltatori din octombrie 2019 va avea loc la San Jose, SUA.

licența LLVM este schimbată de la licența UIUC la licența Apache 2.0 cu excepții LLVM. Este utilizat în principal pentru a rezolva problema că biblioteca LLVM runtime se bazează pe licența MIT, iar autorizația de brevet necesară pentru proiect este prea extinsă. Sub această licență, LLVM permite oricui să obțină produse comerciale din LLVM fără restricții și nu necesită ca niciun derivat să furnizeze cod open source, promovând astfel utilizarea pe scară largă a LLVM, inclusiv:

  1. descărcarea sau utilizarea LLVM în totalitate sau parțial în scopuri personale, interne sau comerciale. Abilitatea de a modifica codul LLVM fără a contribui înapoi la proiect.
  2. crearea unui pachet sau versiune de lansare care conține LLVM. Asocierea LLVM cu codul autorizat de toate celelalte licențe open source majore (inclusiv BSD, MIT, GPLv2 și GPLv3).
  3. când distribuiți LLVM din nou, trebuie să păstrați notificarea privind drepturile de autor. Nu puteți șterge sau înlocui antetul drepturilor de autor. Fișierul binar care conține LLVM trebuie să conțină notificarea privind drepturile de autor.

comparație de performanță între GCC și LLVM

Arhitectură: x86_64
procesor: Intel (R) Xeon (R) Platinum 8163 CPU @ 2.50 GHz
L1 cache de date: 32 KB
L2 cache: 1,024 KB
L3 cache: 33,792 KB
Memorie: 800 GB
sistem de Operare: Alibaba Group Enterprise Linux server release 7.2 (paladin)
nucleu: 4.9.151–015.ali3000.alios7.x86_64
compilator: zăngăni / LLVM 8.0 GCC8.3. 1

Benchmark

SPEC CPU 2017 este un set de instrumente de testare subsistem CPU pentru testarea CPU, cache, memorie, și compilator. Conține 43 de teste din patru categorii, inclusiv SPECspeed 2017 INT și FP care testează viteza întreagă și viteza de funcționare în virgulă mobilă și SPECrate 2017 int și FP care testează rata de concurență întreagă și rata de concurență în virgulă mobilă. Clang nu acceptă limba Fortran. Prin urmare, în acest exemplu, programele C/C ++ din setul de testare SPEC Speed sunt utilizate pentru a testa diferența de performanță single-core între programele binare generate de Clang și GCC. Următorul tabel listează seturile spec CPU2017 C și C++:

CINT2017 SpeedCFP2017 Speed600.perlbench_s619.lbm_s602.gcc_s644.nab_s605.mcf_s620.omnetpp_s623.xalancbmk_s625.x264_s631.deepsjeng_s641.lea_s657.Xz_s

metode de testare

cadrul de automatizare LLVM-lnt este utilizat pentru a efectua testul și a compara performanța. Se rulează în același mod ca și RUNCPU de spec CPU. Înainte de LLVM-lnt rulează, cache (echo 3 > /proc/sys/vm/drop_caches) este șters și apoi rulează setul de date de testare. Apoi, setul de date ref rulează de trei ori. Valoarea medie a celor trei rezultate ale testului ref este utilizată ca rezultat final. Pentru a reduce fluctuațiile de performanță cauzate de migrarea procesorului sau de comutatorul de context, procesele care rulează pe setul de date de testare și setul de date ref sunt legate de un nucleu CPU utilizând instrumentul de afinitate CPU. Pentru testul timpului de compilare, această metodă folosește firul 1 pentru a construi programul de testare și a compara elementele de testare care au fost compilate de mult timp. Timpul de compilare nu include timpul de execuție al linker-ului. Include doar momentul în care sunt generate toate fișierele sursă din toate programele de testare.

compilare comparație performanță

procesul de compilare CCG este după cum urmează: citiți fișierul sursă, preprocesați fișierul sursă, convertiți-l într-un IR, optimizați și generați un fișier de asamblare. Apoi asamblorul generează un fișier obiect. Clang și LLVM nu se bazează pe compilatoare independente, ci integrează compilatoare auto-implementate în backend. Procesul de generare a fișierelor de asamblare este omis în procesul de generare a fișierelor obiect. Fișierul obiect este generat direct din IR. În plus, în comparație cu IR GCC, structura de date a IR LLVM este mai concisă. Ocupă mai puțină memorie în timpul compilării și acceptă traversarea mai rapidă. Prin urmare, Clang și LLVM sunt avantajoase în ceea ce privește timpul de compilare, fapt dovedit de datele obținute din compilarea SPEC, așa cum se arată în figura de mai jos. Clang reduce timpul de compilare cu un singur fir cu 5% până la 10% în comparație cu GCC. Prin urmare, Clang oferă mai multe avantaje pentru construcția de proiecte mari.

compararea timpului de compilare spec

compararea performanței de execuție

majoritatea sarcinilor de lucru cloud necesită ca aplicațiile să poată rula în diferite clustere. Când creați aceste aplicații, nu specificați parametrii legați de mașină. Pentru a se adapta la iterația rapidă cauzată de modificările cererii, sarcinile de lucru în afara spațiilor trebuie, de asemenea, să fie depanabile. Prin urmare, în afară de unele biblioteci stabile și comune care permit niveluri ridicate de optimizare a compilării, volumul de lucru în sine are un nivel scăzut de compilare și optimizare (O2 sau mai jos). Pentru a îndeplini această cerință, acest document compară performanța diferitelor compilatoare la nivelurile de optimizare O2 și O3 pentru programele de viteză INT, așa cum se arată în figura următoare:

compararea performanței vitezei int cpu2017 spec

GCC are un avantaj de performanță de 1% până la 4% față de clang și LLVM pentru majoritatea programelor la nivelurile O2 și O3 și, în medie, are un avantaj de performanță de aproximativ 3% pentru viteza int cpu2017 spec. În termeni de 600.perlbench_s și 602.gcc_s / O2, GCC are un avantaj mare de performanță (mai mult de 10%). Aceste două elemente de testare nu au hotspot-uri remarcabile și pot reflecta efectul cuprinzător de optimizare al compilatorului. Rezultatele testelor arată că GCC este întotdeauna avantajos în optimizarea performanței. Cu toate acestea, pentru două programe legate de AI, inclusiv 631.deepsjeng_s și 641.leela_s, care sunt adăugate recent la testul SPEC, Clang și LLVM îmbunătățesc performanța cu mai mult de 3% în comparație cu GCC. Acest lucru reflectă, de asemenea, progresul rapid al LLVM în ceea ce privește optimizarea. Pentru 625. optimizarea x264_s O2, LLVM îmbunătățește performanța cu 40%, deoarece hotspot-ul cazului respectă regulile vectorizate. Dar Clang și LLVM optimizează vectorii la nivelul O2, în timp ce GCC optimizează vectorii la nivelul O3. Cu excepția programelor vectorizate, GCC nu îmbunătățește foarte mult performanța la nivelul O3 comparativ cu cea la nivelul O2. Cu alte cuvinte, programele nu sunt sensibile la optimizarea GCC O3. În schimb, Clang și LLVM îmbunătățesc semnificativ performanța unor programe (cum ar fi 600. perlbench_s și 602. gcc_s) la nivelul O3.

programele HPC, cum ar fi FP Speed, rulează în general pe servere high-end. Au algoritmi de bază stabili, cerințe ridicate pentru vectorizare și paralelism legate de performanță și permit niveluri ridicate de optimizare (O3 sau mai sus). Prin urmare, acest document compară performanța la nivelul de optimizare O3 + march = native (skylake-avx512), așa cum se arată mai jos:

compararea performanței spec cpu2017 FP speed

pentru cele două programe FP, GCC, de asemenea, poate îmbunătăți performanța cu aproximativ 3%. Clang și LLVM sunt conservatoare în optimizarea buclei și, prin urmare, nu sunt avantajoase în performanță. Cu toate acestea, subproiectul Polly al Clang și LLVM oferă un optimizator de buclă și localitate de date la nivel înalt, care a fost aplicat pe scară largă în învățarea mașinilor, calculul de înaltă performanță și optimizarea calculelor eterogene. Cred că Polly poate îmbunătăți foarte mult performanța programelor care conțin bucle hotspot care respectă regulile de vectorizare și paralelism. De asemenea, voi analiza performanța Polly într-o serie de repere și sarcini de lucru.

concluzii

din testele de benchmarking de mai sus, putem vedea că zăngănit oferă mai multe avantaje pentru construirea de proiecte mari în timp ce GCC este întotdeauna avantajos în optimizarea performanței. Bla depinde de aplicația dvs. specifică

în plus față de compararea performanței, aș dori să împărtășesc avantajele și dezavantajele GCC și zăngănit și LLVM:

avantajele GCC

  • GCC acceptă limbi mai tradiționale decât zăngănit și LLVM, cum ar fi Ada, Fortran, și du-te.
  • GCC acceptă arhitecturi mai puțin populare și acceptă RISC-V mai devreme decât zăngănit și LLVM.
  • GCC acceptă mai multe extensii de limbă și mai multe caracteristici de limbaj de asamblare decât zăngănit și LLVM. GCC este în continuare singura opțiune pentru compilarea kernel-ului Linux. Deși cercetările privind compilarea kernel-ului prin utilizarea Clang și LLVM sunt, de asemenea, raportate în industrie, kernel-ul nu poate fi compilat fără modificarea codului sursă și a parametrilor de compilare.

avantajele Clang și LLVM

  • limbajele emergente folosesc cadrele LLVM, cum ar fi Swift, Rust, Julia și Ruby.
  • Clang și LLVM respectă standardele C și C ++ mai strict decât GCC. GNU inline și alte probleme în timpul actualizării GCC nu apar.
  • Clang acceptă, de asemenea, unele extensii, cum ar fi atributele pentru verificarea securității firului.
  • Clang oferă instrumente utile suplimentare, cum ar fi scan-build și clang static analyzer pentru analiza statică, clang-format și clang-tidy pentru analiza sintaxei, precum și editorul plug-in Clangd.
  • Clang oferă informații de diagnosticare mai precise și mai prietenoase și evidențiază mesajele de eroare, liniile de eroare, solicitările de linie de eroare și sugestiile de reparații. Clang consideră informațiile de diagnosticare ca o caracteristică. Informațiile de diagnosticare au început să fie îmbunătățite numai de la GCC 5.0 și au devenit mature în GCC 8.

(articol Original de Ma Jun Int.)

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *