RSS
 

Posts Tagged ‘multicore’

Cinque rubini nella sfida multicore

19 Aug

Il sistema su cui ho eseguito la prova è un portatile: Dell Inspiron 9400 con Centrino Duo, Intel T7200 4Mb Cache 2Ghz (166×12) Ram 2Gb 667Mhz. Si tratta di un sistema fisico Windows XP pro SP3.

Lo scopo: verificare lo sfruttamento di più core del processore (due nel mio caso) mettendo a confronto un processo singolo con una doppia esecuzione in contemporanea.

Per fare questo ho utilizzato il bench delle stringhe di un articolo precedente.
C’è da tener presente che nell’esecuzione del doppio processo, ognuno deve condividere la cpu con il sistema operativo (il carico è sempre al 100%) mentre nel test singolo questo non succede, un core è dedicato al test mentre l’altro alle altre faccende. Per questo motivo il sistema operativo era privo di antivirus e di altri processi/servizi pesanti.

Cominciamo con il vecchio interprete dell’oneclick installer:

Ruby 1.8.6 patch 111

C:LavoroProgettiTestBench>ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]

C:LavoroProgettiTestBench>ruby bench_str.rb
                           user     system      total        real
Concat 1.000.000:
+                      6.641000   0.000000   6.641000 (  6.640000)
<<                     5.344000   0.000000   5.344000 (  5.375000)
#{}                    6.078000   0.000000   6.078000 (  6.078000)
Add 100.000:
+=                     3.547000   2.969000   6.516000 (  6.579000)
<<                     0.062000   0.000000   0.062000 (  0.062000)
a = a + '.'            3.000000   3.422000   6.422000 (  6.547000)
#{}                    4.531000   1.906000   6.437000 (  6.516000)
Other 100.000:
* 100:                 0.500000   0.063000   0.563000 (  0.562000)
capitalize:            1.719000   0.078000   1.797000 (  1.797000)
upcase:                4.906000   0.140000   5.046000 (  5.047000)
chomp:                 0.266000   0.063000   0.329000 (  0.328000)
include:               1.234000   0.000000   1.234000 (  1.234000)
index:                 1.235000   0.000000   1.235000 (  1.250000)
sub:                   0.875000   0.094000   0.969000 (  0.969000)
gsub:                 17.453000   0.562000  18.015000 ( 18.047000)
[x..y]:                0.547000   0.016000   0.563000 (  0.562000)
slice:                 0.562000   0.000000   0.562000 (  0.563000)
strip:                 0.156000   0.000000   0.156000 (  0.156000)
Each:                 12.282000   0.078000  12.360000 ( 12.390000)
Cast 1.000.000:
.to_i:                 0.437000   0.000000   0.437000 (  0.438000)
.to_sym:               0.531000   0.000000   0.531000 (  0.531000)
split:                 9.047000   0.140000   9.187000 (  9.235000)
--- Total:            80.953000   9.531000  90.484000 ( 90.906000)
Ruby 1.8.6 patch 111

Ruby 1.8.6 patch 111

Singolo:

--- Total:            80.953000   9.531000  90.484000 ( 90.906000)

Multicore:

CORE1:
--- Total:            87.063000  19.531000 106.594000 (107.923000)

CORE2:
--- Total:            91.344000  18.375000 109.719000 (110.125000)

Questo è il decremento del test doppio processo rispetto l'esecuzione singola:
Decremento del 10%
Decremento reale del 20%

Ruby 1.8.6 patch 368

C:LavoroProgettiTestBench>ruby -v
ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]

C:LavoroProgettiTestBench>ruby bench_str.rb
                           user     system      total        real
Concat 1.000.000:
+                      4.828000   0.000000   4.828000 (  4.828125)
<<                     3.938000   0.000000   3.938000 (  3.953125)
#{}                    4.719000   0.016000   4.735000 (  4.750000)
Add 100.000:
+=                     3.687000   2.719000   6.406000 (  6.468750)
<<                     0.047000   0.000000   0.047000 (  0.046875)
a = a + '.'            3.422000   3.000000   6.422000 (  6.468750)
#{}                    4.797000   1.109000   5.906000 (  5.906250)
Other 100.000:
* 100:                 0.328000   0.094000   0.422000 (  0.421875)
capitalize:            0.890000   0.078000   0.968000 (  1.000000)
upcase:                3.469000   0.109000   3.578000 (  3.578125)
chomp:                 0.235000   0.078000   0.313000 (  0.312500)
include:               0.796000   0.000000   0.796000 (  0.796875)
index:                 0.797000   0.000000   0.797000 (  0.796875)
sub:                   0.750000   0.172000   0.922000 (  0.921875)
gsub:                 20.860000   0.531000  21.391000 ( 21.421875)
[x..y]:                0.437000   0.016000   0.453000 (  0.453125)
slice:                 0.438000   0.000000   0.438000 (  0.437500)
strip:                 0.109000   0.000000   0.109000 (  0.109375)
Each:                  9.078000   0.172000   9.250000 (  9.281250)
Cast 1.000.000:
.to_i:                 0.297000   0.000000   0.297000 (  0.296875)
.to_sym:               0.344000   0.000000   0.344000 (  0.343750)
split:                 7.375000   0.109000   7.484000 (  7.500000)
--- Total:            71.641000   8.203000  79.844000 ( 80.093750)
Ruby 1.8.6 patch 368

Ruby 1.8.6 patch 368

Singolo:

--- Total:            71.641000   8.203000  79.844000 ( 80.093750)

Multicore:

CORE1:
--- Total:            80.797000  17.750000  98.547000 ( 99.093750)
CORE2:
--- Total:            76.500000  19.375000  95.875000 ( 97.187500)

Decremento del 9,8%
Decremento reale del 22,5%

Ruby 1.9.1

C:LavoroProgettiTestBench>ruby -v
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-mingw32]

C:LavoroProgettiTestBench>ruby bench_str.rb
                           user     system      total        real
Concat 1.000.000:
+                      2.610000   0.000000   2.610000 (  2.609375)
<<                     2.125000   0.000000   2.125000 (  2.125000)
#{}                    2.796000   0.000000   2.796000 (  2.796875)
Add 100.000:
+=                     3.688000   2.875000   6.563000 (  6.609375)
<<                     0.031000   0.000000   0.031000 (  0.031250)
a = a + '.'            3.235000   3.265000   6.500000 (  6.578125)
#{}                    5.187000   2.266000   7.453000 (  7.546875)
Other 100.000:
* 100:                 0.203000   0.125000   0.328000 (  0.328125)
capitalize:            5.563000   0.047000   5.610000 (  5.656250)
upcase:                0.703000   0.031000   0.734000 (  0.734375)
chomp:                 0.219000   0.063000   0.282000 (  0.296875)
include:               0.156000   0.000000   0.156000 (  0.156250)
index:                 0.156000   0.000000   0.156000 (  0.156250)
sub:                   0.500000   0.093000   0.593000 (  0.593750)
gsub:                  8.453000   0.266000   8.719000 (  8.718750)
[x..y]:                0.219000   0.000000   0.219000 (  0.218750)
slice:                 0.219000   0.000000   0.219000 (  0.218750)
strip:                 0.109000   0.000000   0.109000 (  0.109375)
Each:                  7.188000   0.141000   7.329000 (  7.328125)
Cast 1.000.000:
.to_i:                 0.234000   0.000000   0.234000 (  0.234375)
.to_sym:               0.391000   0.000000   0.391000 (  0.390625)
split:                 4.609000   0.000000   4.609000 (  4.609375)
--- Total:            48.594000   9.172000  57.766000 ( 58.046875)
Ruby 1.9.1 patch 129

Ruby 1.9.1 patch 129

Singolo:

--- Total:            48.594000   9.172000  57.766000 ( 58.046875)

Multicore:

CORE1:
--- Total:            56.345000  19.219000  75.564000 ( 76.312500)
CORE2:
--- Total:            52.109000  20.703000  72.812000 ( 74.156250)

Decremento del 11,5%
Decremento reale del 29,6%

jRuby 1.3.1

C:LavoroProgettiTestBench>jruby -v
jruby 1.3.1 (ruby 1.8.6p287) (2009-07-24 6586) (Java HotSpot(TM) Client VM 1.6.0
_15) [x86-java]

C:LavoroProgettiTestBench>jruby bench_str.rb
                           user     system      total        real
Concat 1.000.000:
+                      1.703000   0.000000   1.703000 (  1.672000)
<<                     1.375000   0.000000   1.375000 (  1.375000)
#{}                    0.625000   0.000000   0.625000 (  0.625000)
Add 100.000:
+=                     8.343000   0.000000   8.343000 (  8.343000)
<<                     0.031000   0.000000   0.031000 (  0.031000)
a = a + '.'            8.406000   0.000000   8.406000 (  8.406000)
#{}                   18.984000   0.000000  18.984000 ( 18.984000)
Other 100.000:
* 100:                 0.157000   0.000000   0.157000 (  0.157000)
capitalize:            0.937000   0.000000   0.937000 (  0.937000)
upcase:                1.703000   0.000000   1.703000 (  1.703000)
chomp:                 0.063000   0.000000   0.063000 (  0.063000)
include:               0.281000   0.000000   0.281000 (  0.281000)
index:                 0.313000   0.000000   0.313000 (  0.313000)
sub:                   0.437000   0.000000   0.437000 (  0.437000)
gsub:                  4.813000   0.000000   4.813000 (  4.813000)
[x..y]:                0.156000   0.000000   0.156000 (  0.156000)
slice:                 0.140000   0.000000   0.140000 (  0.140000)
strip:                 0.047000   0.000000   0.047000 (  0.047000)
Each:                  3.094000   0.000000   3.094000 (  3.094000)
Cast 1.000.000:
.to_i:                 0.609000   0.000000   0.609000 (  0.609000)
.to_sym:               0.266000   0.000000   0.266000 (  0.266000)
split:                 2.203000   0.000000   2.203000 (  2.203000)
--- Total:            54.686000   0.000000  54.686000 ( 54.655000)
jRuby 1.3.1 => 1.8.6 p287

jRuby 1.3.1 => 1.8.6 p287

Singolo:

--- Total:            54.686000   0.000000  54.686000 ( 54.655000)

Multicore:

CORE1:
--- Total:            65.170000   0.000000  65.170000 ( 64.920000)
CORE2:
--- Total:            64.234000   0.000000  64.234000 ( 64.000000)

Decremento del 17,2%
Decremento reale del 17,9%

IronRuby 0.9.0

C:LavoroProgettiTestBench>ir -v
IronRuby 0.9.0.0 on .NET 2.0.0.0

C:LavoroProgettiTestBench>ir bench_str.rb
                           user     system      total        real
Concat 1.000.000:
+                      3.562500   0.000000   3.562500 (  3.234375)
<<                     1.531250   0.000000   1.531250 (  1.531250)
#{}                    1.453125   0.015625   1.468750 (  1.453125)
Add 100.000:
+=                    54.656250  11.296875  65.953125 ( 66.171875)
<<                     0.031250   0.000000   0.031250 (  0.031250)
a = a + '.'           54.734375  11.718750  66.453125 ( 66.671875)
#{}                   55.609375  10.843750  66.453125 ( 66.609375)
Other 100.000:
* 100:                 0.671875   0.000000   0.671875 (  0.671875)
capitalize:            2.593750   0.000000   2.593750 (  2.609375)
upcase:                7.484375   0.000000   7.484375 (  7.500000)
chomp:                 0.250000   0.000000   0.250000 (  0.250000)
include:               5.968750   0.015625   5.984375 (  6.031250)
index:                 5.968750   0.031250   6.000000 (  6.031250)
sub:                   1.781250   0.015625   1.796875 (  1.781250)
gsub:                 12.203125   0.031250  12.234375 ( 12.281250)
[x..y]:                0.406250   0.000000   0.406250 (  0.390625)
slice:                 0.343750   0.000000   0.343750 (  0.343750)
strip:                 0.078125   0.000000   0.078125 (  0.078125)
Each:                 31.546875   0.312500  31.859375 ( 32.203125)
Cast 1.000.000:
.to_i:                 0.265625   0.000000   0.265625 (  0.250000)
.to_sym:               0.406250   0.015625   0.421875 (  0.421875)
split:                 5.515625   0.031250   5.546875 (  5.531250)
--- Total:           247.062500  34.328125 281.390625 (282.078125)

C:LavoroProgettiTestBench>
IronRuby 0.9.0

IronRuby 0.9.0

Singolo:

--- Total:           247.062500  34.328125 281.390625 (282.078125)

Multicore:

CORE1:
--- Total:           315.531250  40.578125 356.109375 (359.500000)
CORE2:
--- Total:           300.484375  46.156250 346.640625 (350.265625)

Decremento del 24,5%
Decremento reale del 25,8%

Riepilogo

Ruby 1.8.6 patch 111
Decremento del 10%
Decremento reale del 20%

Ruby 1.8.6 patch 368
Decremento del 9,8%
Decremento reale del 22,5%

Ruby 1.9.1
Decremento del 11,5%
Decremento reale del 29,6%

jRuby 1.3.1
Decremento del 17,2%
Decremento reale del 17,9%

IronRuby 0.9.0
Decremento del 24,5%
Decremento reale del 25,8%

Conclusioni

Non so cosa sarebe successo con altri test ma in questo, jRuby è l'unico che ha un carico uniforme sui due core e lo fa costantemente quasi per tutta la durata. Solo alla fine si sposta verso un core ma con più discrezione. Ottima anche la prestazione con i due processi in contemporanea.

Le versioni 1.8.6 e 1.9.1 sono abbastanza allineate e riescono a spartire il carico solo sui test "Add". La prestazione del doppio processo non sarebbe male ma crea qualche difficoltà al sistema (almeno al mio) che ne allunga i tempi.

IronRuby ha qualche problemino con le stringhe già evidenziato in un articolo precedente. Ignorando questo, non ha sfruttato il secondo core che è rimasto scarico per tutta la durata. Col secondo core libero, mi sarei aspettato un decremento meno evidente nel test del doppio processo ma così non è stato, questo è strano!

In un prossimo articolo, mi piacerebbe ripetere il test su un server quad core.

 
Comments Off

Posted in IronRuby .NET, JRuby, Ruby