After reaching initial stages of the x86-64 JIT, work on a long overdue enhancement of the DWScript engine has started: refactoring how dynamic arrays are implemented.
One of the goals when the 32bit JIT was introduced was to edge out the Delphi 32bits compiler, which was not too complicated as Delphi was using the FPU, so merely using SSE2 at the time was enough. But the Delphi 64bits compiler makes good use of SSE2, so the only way to edge it out would be to leverage AVX2 and vectorisation.
Variant Dynamic Arrays
However, DWScript internals are historically using the Variant type everywhere. Low-level bypasses are used in cases when the script-side type is strongly-typed, which eliminates the Variant overhead in many cases. This is and was very convenient, but became more and more limiting:
- it became more wasteful: with 64bit Delphi versions, the size of a Variant went from 16 bytes to 24 bytes, while the largest DWScript data type is 8 bytes long. That is now a 3 to 1 waste.
- it impacts potential performance: the data stride imposed by the Variant size makes SIMD instructions very inefficient. Scripts will also run into memory bandwidth limits (CPU Cache) very quickly
While it would eventually be nice to no longer rely on the Variant type everywhere, that would require a significant amount of work, and the Variant is mostly a bottleneck for arrays.
So what’s happening ?
- The internal dynamic array interfaces are being decoupled from the other storage interfaces (stack & object instances), more decoupling will take place so that implementations will no longer have to expose “naked” variants.
- Classes and utilities will be shuffled around to newer units, if you forked the code and applied patches, this could wreak some havoc. If you used the internal types directly, you may have to adapt your “uses”.
- In cases where there is a choice between decoupling and performance, decoupling will take precedence, the performance aspects will be taken over by the JIT compiler.
The idea is that ultimately the JITted code could run way faster with much less memory. Non-JITted code on the other hand may experience lower performance. This would especially be the case for scripts that do not rely on strongly-typed types.