Přiznejme si to, optimalizace výpočtů s floating point měla v Delphi rezervy. Kód produkovaný dcc32 je schopen běžet (myslím) i na obyčejném Pentiu a optimalizován pro procesory Pentium Pro (resp. aspoň minulé verze) a využívá normální koprocesor. Samozřejmě některé knihovny (FastCode) umožňují využívat MMX, SSE atd. ale v základu to je vždy normální koprocesor.
S nástupem dcc64 je situace jiná. 64bit kód se dá provádět jen 64bit procesorem a ten musí obsahovat SSE2 jednotku. Takže veškeré operace jsou za použití SSE2 nebo tak nějak.
Používaným numerickým benchmarkem je SciMark2 (Delphi port).
Pamatujme, že se jedná o první verzi kompilátoru a zdaleka nejsou všechny optimalizace zapnuté.
** **
** SciMark2a Numeric Benchmark, see http://math.nist.gov/scimark **
** **
** Delphi Port, see http://code.google.com/p/scimark-delphi/ **
** **
Delphi XE
Mininum running time = 2,00 seconds
Composite Score MFlops: 380,59
FFT Mflops: 116,47 (N=1024)
SOR Mflops: 620,60 (100 x 100)
MonteCarlo: Mflops: 74,81
Sparse matmult Mflops: 323,16 (N=1000, nz=5000)
LU Mflops: 767,90 (M=100, N=100)
Delphi XE2 - 32 bit
Mininum running time = 2,00 seconds
Composite Score MFlops: 402,50
FFT Mflops: 121,03 (N=1024)
SOR Mflops: 633,45 (100 x 100)
MonteCarlo: Mflops: 98,87
Sparse matmult Mflops: 337,38 (N=1000, nz=5000)
LU Mflops: 821,75 (M=100, N=100)
Delphi XE2 - 64 bit
Mininum running time = 2,00 seconds
Composite Score MFlops: 525,57
FFT Mflops: 390,91 (N=1024)
SOR Mflops: 417,27 (100 x 100)
MonteCarlo: Mflops: 122,07
Sparse matmult Mflops: 703,18 (N=1000, nz=5000)
LU Mflops: 994,42 (M=100, N=100)
Abych se přiznal, musel jsem test v modu 64bit opravit, protože přetekl rozsah (z Integer na Int64). Mimochodem je tak 64bit verze rychlejší než uvedená verze na stránkách v C# (skóre 493MFlops). Ale pamatujte: nevěřte žádnému benchmarku, který si nezfalšujete.
Ještě ohledně SSE a X64. Např. následující kód (system.pas): první část je pro 64bit verze, druhá část je 32bit verze (většinou stejná jako v předchozích verzích Delphi). Ne vždy je to takto výrazné - může to být naopak.
{$IF defined(CPUX64)}
function _Trunc(Val: Extended): Int64;
asm
.NOFRAME
CVTTSD2SI RAX, XMM0
end;
{$ELSEIF defined(CPUX86)}
procedure _Trunc;
asm
{ -> FST(0) Extended argument }
{ <- EDX:EAX Result }
SUB ESP,12
FNSTCW [ESP].Word // save
FNSTCW [ESP+2].Word // scratch
FWAIT
OR [ESP+2].Word, $0F00 // trunc toward zero, full precision
FLDCW [ESP+2].Word
FISTP qword ptr [ESP+4]
FWAIT
FLDCW [ESP].Word
POP ECX
POP EAX
POP EDX
end;
{$IFEND}
Direktiva assembleru .NOFRAME určuje, že tato funkce je slepá (tj. nevolá další funkce) a proto pro ni není třeba generovat rámec zásobníku (nebo jak se to jmenuje), což je jinak nutné pro 64bit kód na Windows (jedná se o požadavek Windows).