With XE2 now officially out [1], it’s time for a first look at Delphi XE2 compiler floating point performance (see previous episode [2]).
For a first look I’ll reuse a Mandelbrot benchmark, based on this code Mandelbrot Set in HTML 5 Canvas [3]. What it tests are double-precision floating-point basic operations (add, sub, mult) in a tight loop, there is relatively little in the way of memory accesses (or shouldn’t be, to be more accurate).
You can find the source code see there [2], it compiles pretty much straight away in XE2 (just comment out the asm for Win64).
NOTE: when this article was originally posted, I had stumbled upon an XE2 Trial version “trap” (or feature?) which basically deactivated Win64 optimizations as defined through the project options. Kenji Matumoto pointed the issue, and this is an updated article where I used {$O+} in the code to “force” optimizations. The outcome is a *much* prettier picture, I’m happy to say! Reservations from the initial articles are gone, good job Embarcadero!
edit 05/09, after further tests, I’m adding one reservation single-precision floating point doesn’t look so hot. More on the subject there [4].
Benchmark results
Without further ado, here are the raw figures on my machine for the 480 x 480 case, keep in mind the Delphi versions do NOT use Canvas.Pixels[], but direct memory access in an array:

Execution time in milliseconds, lower is better
Or if you prefer hard figures:
- Delphi XE2 – 32 bits: 193 ms
- Delphi XE2 – 64 bits: 67 ms — fastest Delphi
- Delphi XE: 196 ms
- FireFox 6: 121 ms
- Chrome 13: 74 ms
- (out of competition: XE 32bit hand-made assembly: 57 ms)
So what gives?
- XE2 32bit compiler still uses the old FPU code, the performance delta with XE is minimal and could just be an alignment issue (pseudo-random, since the compiler doesn’t pro-actively align). Let’s hope the SSE2 codegen will be retrofitted in XE3.
- XE2 64bit compiler get a nice boost from using SSE2, allowing it to catch up and overtake all JavaScript JITters.
- Chrome V8 makes a good showing in this benchmark, but loses the crown, native Delphi is back on top!
A peek under the hood
What does the compiler generate for the two following lines?
x := x0 * x0 - y0 * y0 + p; y := 2 * x0 * y0 + q;
Once you pop up the CPU view, you’ll see:
FMandelTest.pas.193: x := x0 * x0 - y0 * y0 + p; 00000000005A1452 660F28C4 movapd xmm0,xmm4 00000000005A1456 F20F59C4 mulsd xmm0,xmm4 00000000005A145A 660F28CD movapd xmm1,xmm5 00000000005A145E F20F59CD mulsd xmm1,xmm5 00000000005A1462 F20F5CC1 subsd xmm0,xmm1 00000000005A1466 F20F58C2 addsd xmm0,xmm2 FMandelTest.pas.194: y := 2 * x0 * y0 + q; 00000000005A146A 660F28CC movapd xmm1,xmm4 00000000005A146E F20F590DA2000000 mulsd xmm1,qword ptr [rel $000000a2] 00000000005A1476 F20F59CD mulsd xmm1,xmm5 00000000005A147A F20F58CB addsd xmm1,xmm3
And further down the code, the compiler makes use of xmm8, so it’s really aware of the 16 xmm registers you have in x86-64, and finally keeps floating point values in registers, something the 32bit compilers (both XE & XE2) don’t do.
To what does it lose to the hand-made asm version? Well, a handful of minor things:
- even though it used up to 9 xmm registers, it didn’t use a 10th, leaving some memory access
- with more careful allocation, it could have fit everything in 8 xmm registers, which would have cut unnecessary traffic
- it zeroes registers with a move from memory, and didn’t do constant unification or propagation.
Still those are mostly nitpickings compared to the massive issues of the old FPU code compilation (which, alas XE2 – Win32 still suffers from).
Conclusion
Support for SSE2 in XE2 64bit compiler consists in a significant step ahead for Delphi floating point performance. XE2 32bit is still same old.
If you’re doing heavy floating point maths, XE2 64bit compiler is a simple ticket to much better performance.
Hopefully in Delphi XE3 they will retrofitting the SSE2 codegen into the 32bit compiler, but ad interim it should quell all the critics about “we don’t need no 64bit”, well, if you do any significant floating-point maths, Delphi XE2 64bit is a must!