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)
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)
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)
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)
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>
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.




