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ň