[fpc-pascal] Effective memory allocation

Sven Barth pascaldragon at googlemail.com
Mon Nov 3 07:39:42 CET 2014

On 03.11.2014 02:59, Xiangrong Fang wrote:
> 2014-11-03 2:50 GMT+08:00 Sven Barth <pascaldragon at googlemail.com
> <mailto:pascaldragon at googlemail.com>>:
>     If you use SetLength the dynamic array consists not only of the
>     array data, but also of an information record in front of it. This
>     will likely lead to the data not being aligned correctly (FillQWord
>     works best with 8-Byte alignment). So what about testing FillDWord
>     or FillChar? Just to see whether they would be faster.
> ‚ÄčIt is quite strange that if I use SetLength+FillByte, it is really
> faster (for the FillByte), but if I use GetMemory+FillByte, it is not
> faster than using FillDWord or FillQWord.

Then it's indeed as I suspected. The memory buffer itself that is 
allocated by SetLength is allocated, but the pointer returned to you 
(what you get as a dynamic array) has - at least for FillQWord - a bad 
alignment. Looking at the source though it should still be 8-Byte 
aligned though (the information record has a size of 8 on 32-bit 
systems)... *sigh*

Please also note that not on every system the Fill* methods are 
implemented in assembler. FillChar mostly is, FillWord and FillDWord 
perhaps, but FillQWord mostly seldomly (it's e.g. not even implemented 
that way on x86_64). So especially on 32-bit system 2 32-bit moves are 
used each. Thus FillQWord is not always the optimal choice and I'd 
suggest that you time the different Fill* functions especially on 
different platforms.

Would you mind to show the timings that you got for FillChar? :)

> I found this in FPC doc (for $ALIGN switch):
> This switch is recognized for Turbo Pascal Compatibility, but is not yet
> implemented. The alignment of data will be different in any case, since
> Free Pascalis a 32-bit compiler.
> ‚ÄčIt is a pity that this switch is not recognized yet. But I need to
> understand the last statement, will alignment be different or not?

I think that last statement is ment regarding that Turbo Pascal is a 
16-bit compiler which had different alignment values available than FPC 
needs. I don't know what TP supported back then, but I don't imagine 
that it supported e.g. 16-Byte alignment.

Additionally this switch won't help you. The memory buffer that is 
allocated by SetLength is also allocated using GetMemory. So the buffer 
itself *is* aligned. But you don't get the start byte of the buffer in 
case of SetLength, but the first byte after the information record which 
might not be aligned correctly and *no* compiler switch will help you 
with that.


More information about the fpc-pascal mailing list