Zdroják v c, a v pascalu Pro testy jsem použil pentium/100 na 120, 512KB burst cache pod dosem s himemem. Borlandí kompiler vlastním ve verzi 2.0 (já vím, že verze x.y je nejméně pětkrát rychlejší) a proto jsem udělal také test pod borland pascalem 7.0. Snažil jsem se všechny kompilery donutit k co nejlepším výsledkům. U bc to bylo snadné. Ať jsem měnil, co měnil pořád byl čas stejný. U paskalu jsem zapnul koprocesor, 286 instrukce a vypnul kontroly. Zdroják jsem se snažil napsat co nejoptimálněji. To pomáhá borlandům, protože všechny změny (úprava výpočtů, obrácení smyčky..) nezměnily výsledný čas. Ve škole jsem potom dodělal daší testy na ostatních kompilerech. No abych nezdržoval tady je tabulka: +----------+------------------------------------+------------------+ |kompiler |optiony | Smyček za sekundu| +----------+------------------------------------+------------------+ |gcc2.6.3 |-O3 -ffast-math -m486 | 4 233 641 | | |-fomit-frame_pointer -funroll-loops | | |gcc2.7.2.1|-O3 -ffast-math -m486 | 4 149 377 | | |-fomit-frame_pointer -funroll-loops | | |pgcc2.7.2 |-O6 -ffast-math -m586 -frisc | 3 436 426 | | |-fomit-frame_pointer -funroll-loops | | |gpc2.0 |-O3 -ffast-math -m486 | 3 433 962 | | |-fomit-frame_pointer -funroll-loops | | |wc10.0 | -7 -5 -ol -ol+ -om -op -or -ot -fp5| 2 222 222 | | | -fpi87 | | |wc10.0 | -5 -7 | 2 217 249 | |plan9 |<v IDE-586,speed+size optim.> | 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 | | 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 | | 716 535 | |bc2.0 |-G -O -2 -Z -r | 716 535 | |tc2.0 | | 546 546 | |bc4.0 |<v IDE-486,speed+size optim.> | -3.6676456... | +----------+------------------------------------+------------------+ Vc znamená visual C++ 1.0. Gcc 2.6.3 bylo použito v DJGPP 1.0. Wc znamená watcom C 10.0. Pgcc je experimental gcc pro pentium od Intelu. Plan9 je kompiler ve stejnojmeném OS (který je mimochodem také free a velice zajímavý) Ještě zajímavější je, že tento kompiler ma pouze cca 200KB a tak je suveréně nejjednodušší. Gpc je GNU pascal compiler Jak je vidět borlandí C je 5.77krát pomalejší. Pascal je na tom o něco lépe tedy 4.58 krát. Asemblerový zdroják se mi podařilo získat jenom z borlandího C a gcc. Napočítal jsem 20 instrukcí v interní smyčce u GNU a 35 u borlandů. Novější Borlandi se celkem slušně vylepšili. Ve verzi 4.5 je už "poze" 2.6krát pomalejší. Naprosto mě ale překvapil test ve verzi 4.0. Tam se zpomalil a po zapnutí optimizací na velikost se program natolik zrychlil, že získal záporný čas. Nevím, jak někdo může tak zabugovaný compiler pustit do světa. Další zajímavá věc ohledně Borlandů je to, že ve verzi 3.1 byl .exe dlouhý 14KB, ve verzi 4.0 už 48KB a v 4.5 celých 61KB.V posledních borlandech jsem napočítal 34 instrukcí v interní smyčce. FractalZoom, který má smyčku v assembleru se pyšní 22 instrukcema a jeho test říka 3.9 milionů smyček za sekundu. Zajímavé je, že staré gcc vyšlo z testu o 2.2% lépe. Ale bude to spíš chyba měření, protože interní smyčka je stejná. Naprosto mě zklamalo watcom C. Měl jsem ho zafixované jako velmi dobrý kompiler ale přes to, že narozdíl od gcc podporuje pentium, scheluding instrukcí pro pentium, a fp optimalizace pro pentia bylo téměř dvakrát pomalejší. Pro GNU pascal jsem musel zdroják poupravit tak, aby používal céčkovou fci clock pro testování času a __long__ integer místo integeru protože normální 16 bit integery jsou strašně pomalé. Přesto ale je GNU pscal ze záhadných důvodů pomalejší než C. Asm z gcc, a borlandu Aby se neřeklo, že se starám pouze o MS-DOS provedl jsem ještě testy na sunech a siliconech gcc versus kompiler dodávaný s OS. Tady jsou výsledky: SUN +----------+------------------------------------+------------------+ |kompiler |optiony | Smyček za sekundu| +----------+------------------------------------+------------------+ |gcc2.7.0 |-O3 -ffast-math -fomit-frame-pointer| 925 925 | | | -funroll-loops | | |cc |-O | 840 336 | +----------+------------------------------------+------------------+ SGI +----------+------------------------------------+------------------+ |kompiler |optiony | Smyček za sekundu| +----------+------------------------------------+------------------+ |gcc2.7.0 |-O3 -ffast-math -fomit-frame-pointer| 2 688 172 | | | -funroll-loops | | |cc |-O | 2 096 436 | +----------+------------------------------------+------------------+ Musím říct, že výsledek mě OPRAVDU překvapil. Výsledky jsou mnohem vyrovnanější, než u dosových kompilerů. Napadly mě následující vysvětlení: 1) GCC generuje horší kód na neintelových platformách 2) SUN a SGI odělali tak dobrý kompiler, že mu všechny komerční DOSové nesahají ani po kotníky 3) Sparc a Mips mají jednodušší práci s floating point registry a proto generování kodu pro ně je jednodušší. Proto jsem udělal další test. Nahradil jsem long double za int. Teď je už celá matematika jednoduchá i na intelu a udělal další test: +----------+------------------------------------+------------------+ |kompiler |optiony | Smyček za sekundu| +----------+------------------------------------+------------------+ |pgcc2.7.2 |-O6 -ffast-math -frisc | 3 267 245 | | |-fomit-frame_pointer -funroll-loops | | |gcc2.7.2.1|-O3 -ffast-math -m486 | 3 250 000 | | |-fomit-frame_pointer -funroll-loops | | |wc10.0 |-fpi87 -fp5 -5 -7 -ol -ol+ -om -on | 3 246 753 | | |-or -ot | | |wc10.0 |-5 -7 | 3 194 888 | |plan9 | | 2 973 176 | |gpc2.0 |-O3 -ffast-math -fstrength_reduce | 2 888 888 | | |-fomit-frame_pointer -funroll-loops | | |gcc2.7.2.1| (bez optimalizace) | 2 394 736 | |gpc2.0 | (bez optimalizace) | 2 219 512 | |bc2.0 |-G -O -2 -Z -r | 2 166 666 | |bp7.0 | | 1 956 947 | |tc2.0 |-1 -O -r -G -Z -a -mt | 892 156 | |tc2.0 | | 846 511 | +----------+------------------------------------+------------------+ Výsledek mě opět překvapil. Zpomalení u gcc jsem nečekal. Po prozkoukání assembleru jsem zjistil, že tam není nic, co bych byl schopný nějak radikálně zoptimalizovat - všechno je v registrech a smyčka se zkrátila na 14 instrukcí snad jenom ty dva skoky, ale když jsou tu dvě podmínky a ve floatng point verzi byly taky.... Pentium má mul pomalejší než fmul a tak se výsledek asi dal očekávat. Samozdřejmě to neplatí o 486. Gcc s experimentálníma pentiovýma patchema sice smyčku trochu přerovná ale pomůže to jen o cca 1%. Pořád je ale Borland o hodně pomalejší. To, že gcc by generovalo na mipsech horší kod se mi zdá nepravděpodobné, protože optimizery jsou z velké části nezavislé na architektuře. a tak si myslím, že to bude tak půl na půl mezi lepší architekturou a tím že lidi kolem UNIXu lépe programují. Myslím, že testy mluví samy za sebe a ukazují, že tady GNU odvedlo opravdu dobrou práci. Psaní rutin v assembleru, aby byly rychlejší už skoro nemá smysl. Je to důvod, proč programy v linuxu bývají rychlejší (klasický příklad je doom). Má to bohužel i nevýhodu. Přežhavené stroje často programy kompilované pomocí gcc nevydrží (moje 486DX2 normálně pracující v pokojové teplotě se při kompilaci jádra zahřeje tak, že na ní neudržím ruku). Lidi si často myslí, že je to chyba programu. Taky proces kompilace je docela složitý a tak to kompileru chvíli trvá. Poslední dost důležitá věc je to, že oproti Borlandum je gcc téměř bez bug. Za asi 6 let, co na něm dělám jsem narazil asi na tři problémy. Jinak vždycky všechno fungovalo. výheň