P°ekladaΦ


If the Tao is great, then the operating system is great. If the operating system is great, then the compiler is great. If the compiler is great, then the application is great. If the application is great, then the user is pleased and there is harmony in the world.

The Tao gave birth to machine language. Machine language gave birth to the assembler.

The assembler gave birth to the compiler. Now there are ten thousand languages.

Each language has its purpose, however humble. Each language expresses the Yin and Yang of software. Each language has its place within the Tao.

But do not program in COBOL if you can avoid it.

-- Geoffrey James, The Tao of Programming

Nejd∙le╛it∞j╣φ GNU program je nesporn∞ p°ekladaΦ. Ten umo╛nil, aby vzniklo v╣echno ostatnφ. Jednß se o jeden z nejkvalitn∞j╣φch p°ekladaΦ∙ v∙bec - je snadno p°enositeln² na novou architekturu (jednß se pouze o napsanφ n∞kolika soubor∙ s popisem architektury a pro generovßnφ assembleru), umφ p°eklßdat mnoho r∙zn²ch jazyk∙ (nenφ tedy t°eba jeden p°ekladaΦ pro Pascal a jin² pro C) a mß v²born² optimizer.

P°eklad se provßdφ pomocφ mezijazyku zvenΘho Register transfer language (RTL). Ten je navr╛en tak, aby zast°e╣il rozdφly mezi vstupnφmy jazyky a vφstupnφ platformou a je velmi vhodn² pro optimalizace. Narozdφl od v∞t╣iny ostatnφch p°ekladaΦ∙ je ale sv²m zp∙sobem zßvisl² na cφlovΘm procesoru a proto GNU C dokß╛e svΘ optimalizace dob°e p°izp∙sobit specifick²m pot°ebßm danΘ platformy.

Provßd∞jφ se tyto zßkladnφ optimalizace:

Optimalizace skok∙
zru╣enφ skok∙ na skoky
Scanovßnφ registr∙
tady se najde, kdy kter² registr (krycφ nßzev pro prom∞nnou) byl pou╛it poprvΘ a naposled
Optimalizace skok∙ na stejn² nebo opaΦn² test
ty mohou b²t vynechßny
Propagace konstant, eliminace v²raz∙
propagace konstant se sna╛φ dosadit konstanty za registry. Odstra≥uje v²razy bez v²stup∙ a vedlej╣φch efekt∙ a vyhodnocuje v²razy bez vstup∙. To v²razy zkracuje, vyhodφ nepot°ebnΘ Φßsti programu atd.
Optimalizace smyΦek
Sna╛φ se v╣echno, co jenom jde, dostat mimo smyΦku. Znova prob∞hne eliminace expresion.
Anal²za toku dat
Rozd∞lφ program do blok∙, vyhazuje nedosa╛itelnΘ smyΦky, a zji╣╗uje, kde kter² registr je ╛iv² - to znamenß, ╛e je t°eba uchovßvat jeho hodnotu - najde v²poΦty, kde v²sledek nenφ pou╛it.
Kombinace instrukcφ
(ne assemblerov²ch, ale t∞ch RTL) Spojuje instrukce, kterΘ jdou sjednotit do jednΘ, pou╛φvß algebru na optimalizaci matematick²ch v²raz∙ a p°id∞lφ RTL k≤du opravdovΘ instrukce, kterΘ odpovφdajφ popisu procesoru. (ano, tato Φßst je ΦßsteΦn∞ zßvislß na architektu°e).
Scheduling instrukcφ
posklßdß instrukce pro superskalßrnφ riscovΘ procesory tak, aby bylo mo╛nΘ jich provßd∞t vφce narßz. Verze 2.8.0 (kterß je╣t∞ nenφ) to bude d∞lat i pro Pentia a Pentia pro.
T°φdy registr∙
hardwarovΘ registry majφ n∞kolik t°φd. Tak t°eba pam∞╗ (zßsobnφk), registry procesoru, registry koprocesoru. Tato Φßst rozhodne, kterΘ t°φdy registr∙ lze pou╛φt pro ten dan² pseudoregistr.
Alokace registr∙
tady se koneΦn∞ rozhodne, kterΘ prom∞nnΘ budou ve v²slednΘm programu ulo╛eny a kdy.
Globßlnφ alokace registr∙
to samΘ, ale pro globßlnφ prom∞nnΘ.
Reloading
tady se dosadφ hardwarovΘ registry registr∙m a zbytek se ulo╛φ do zßsobnφku.
Dal╣φ scheduling
aby se instrukce nehßdaly o pam∞╗, potom se opakuje optimalizace skok∙ a je╣t∞ jednou scheduling
optimalizace zßsobnφkov²ch registr∙
to je specißln∞ pro koprocesor i386
P°evod do assembleru
a dφlo je hotovo.

Samoz°ejm∞, ╛e p°ekladaΦ provßdφ i mnoho dal╣φch mal²ch optimalizacφ.

Znalci assembleru mo╛nß docenφ v²sledn² k≤d nßsledujφcφho p°φkladu:

      main()
      {int i,a=1,b=0;
          for(i=0;i<9999;i++)
          a=a+b,b=2*a;
          printf("%i\n",a);
      }

V²sledek z GCC a Borland C 2.0.

Srovnßnφ s ostatnφmi

Toto je malΘ ilustraΦnφ srovnßnφ. Testuji zde jen jeden mal² program a proto v²sledky nejsou p°φli╣ p°esnΘ, ale ukazujφ, ╛e GCC si opravdu nestojφ ╣patn∞. K test∙m jsem se rozhodl pou╛φt v²poΦet Mandelbrotovy mno╛iny. Je to netrivißlnφ, koprocesor vyu╛φvajφcφ smyΦka z reßlnΘho ╛ivota. Tak se p°ekladaΦ mß co Φinit.

Zdrojov² k≤d v C, a v Pascalu

Pro testy jsem pou╛il Pentium/100 na 120, 512KB burst cache pod Φist²m DOSem s himem.sys. Sna╛il jsem se v╣echny p°ekladaΦe donutit k co nejlep╣φm v²sledk∙m.

Kompilßtor p°epφnaΦe SmyΦek za sekundu
pgcc2.7.2p -O6 -ffast-math -mpentium -frisc -fomit-frame-pointer -funroll-loops-fopt-reg-use -frisc 5 464 480
egcs-1.0 -O3 -ffast-math -mpentium -fomit-frame-pointer -funroll-loops 5 405 405
egcs-1.0+HAIFA -O3 -ffast-math -mpentium -fomit-frame-pointer -funroll-loops 5 005 005
egcs-1.0 -O3 -ffast-math -m486 -fomit-frame-pointer -funroll-loops 4 807 692
gcc2.6.3 -O3 -ffast-math -m486 -fomit-frame-pointer -funroll-loops 4 233 641
gcc2.7.2.1 -O3 -ffast-math -m486 -fomit-frame-pointer -funroll-loops 4 419 377
gpc2.0 -O3 -ffast-math -m486 -fomit-frame-pointer -funroll-loops 3 433 962
wc11 -7 -5 -ol -ol+ -om -op -or -ot -fp5 -fpi87 3 090 090
vc5.0 (optimalizace na max) 3 060 908
wc10.0 -7 -5 -ol -ol+ -om -op -or -ot -fp5 -fpi87 2 222 222
wc10.0 -5 -7 2 217 249
delphi max. speed 1 807 288
plan9 default 1 623 376
vc1.0 (v IDE-586,speed+size optim.) 1 531 393
bc4.5 (v IDE-486,fastest executable) 1 455 604
bc3.1 (v IDE-386,fastest executable) 1 433 070
gcc2.7.2.1 (bez optimalizacφ) 1 281 348
gpc2.0 (bez optimalizacφ) 1 109 756
bp7.0 max. speed 901 713
tc2.0 -1 -f87 -O -r -Z -G -a -mt 846 511
bc4.0 (v IDE-486,speed optimizations) 755 857
bc2.0 (bez optimalizacφ) 716 535
bc2.0 -G -O -2 -Z -r 716 535
tc2.0 max. speed 546 546
bc4.0 (v IDE-486,speed+size optim.) -3.6676456...

Vc znamenß Visual C++ 1.0/5.0. GCC 2.6.3 bylo pou╛ito v DJGPP 1.0. Wc znamenß Watcom C. Plan9 je kompilßtor ve stejnojmennΘm OS. Gpc je GNU Pascal compiler. Egcs je od╣t∞penß v∞tev od v²voje GCC 2.8.0. Nynφ je oficißlnφ verzφ GCC 2.95.0 PGCC je GCC pro Pentium, ktere p∙vodn∞ zaΦal vyvφjet Intel. Potom co dosßhl 30% urychlenφ ve smφ╣en²ch benchmarkßch, nechal v²voje a uvolnil zdrojovΘ k≤dy. V²voje se ujala skupina jmΘnem Pentium Support Group, kterß odstranila velkou Φßst chyb, kterΘ Intel zavedl, p°idala podporu PentiaPro, k5, k6 a Cyrixe.