Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-10

Pre-zeroing in MM by background thread/process

3 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Adem

I did a global search on trunk\compiler and found the following numbers:

GetMem(): 212 hits
FillChar(): 362 hits

I haven't checked any other fpc folder, but I am sure those figures would multiply.

What I did notice was that GetMem() and FillChar() were being used in pairs most of the time --as opposed to using AllocMem() which had 16 hits.

My focus isn't on the merits of using AllocMem() instead of GetMem() and FillChar() pair; what I do notice is the fact that in a lot of places there is a strong need for zeroed memory.

That brings me to the idea of handling the zeroing of memory chunks by the memory manager (MM) instead of doing it in-line.

But, before getting grilled to death here, I floated this idea in forums.codegear.

Here it is:
nntp://forums.codegear.com/embarcadero.public.delphi.language.basm/848

[Quite a bit of the following text is taken from Thorsten Engler's replies to my and other's questions on the topic. For more detail please read the above NNTP thread]

The basic idea is this: In the memory manager a background (idle priority) thread/process does the zeroing --preferably using another core.

The idea isn't entirely new; Windows has been doing just that for over a decade (since Win98 and NT3.1). It is pre-zeroing pages in a background thread and making them available to applications through VirtualAlloc() calls.

In Windows, an idle priority background thread takes pages from the 'Free' list, zeroes them, and puts them into the 'Zeroed' list.

That way, when a new physical page is required, it can directly be taken from the 'Zeroed' list. Only if a new page is required and the 'Zeroed' list is empty is a page directly taken from the 'Free' list and zeroed JIT.

'Free' page count (which are pages that have been returned to the page pool, but which still contain whatever it is they contained before being freed) are always pretty close to 0, while the 'Zeroed' page count is usually much higher (except if the system is running out of physical memory).

This does not seem to have noticeable impact on Windows or else MS would have --I think-- given up on that long ago.

Now, back to the MM in FPC:

Obviously, zeroing is a waste of time for any allocation where it is not required. But all allocations for classes DO require it. And besides strings and dynamic arrays, classes a pretty much the major part of all allocations.

So, it seems, if we had something like what Windows has, we could get rid of all those GetMem() and FillChar() pairs and replace them with AllocMem() [and ReAllocZeroMem()] that retrieves pre-zeroed memory from the MM and increase the overall performance.

The worst case scenario would be this: MM doesn't have any 'Zeroed' memory. In which case, AllocMem() falls back to GetMem() and FillChar() pair.

Under Windows, MM could get intial zeroed memory through VirtualAlloc() to begin with and then zero only the returned memory.

I did try to lookup an equivalent to VirtualAlloc() and it seems calloc() is it --but I am not sure if it is, or whether it is available in all platforms.

Anyway, this is the idea.

I wonder what you think.

---------------
More hit data:

fpc/trunk/packages/
GetMem(): 1464 hits
FillChar(): 608 hits

trunk/lazarus/
GetMem(): 522 hits
FillChar(): 1366 hits

Cheers, Adem

Reply by email

Florian Klaempfl
to Adem
Adem wrote 17 lines
I did a global search on trunk\compiler and found the following numbers: GetMem(): 212 hits FillChar(): 362 hits I haven't checked any other fpc folder, but I am sure those figures would multiply. What I did notice was that GetMem() and FillChar() were being used in pairs most of the time --as opposed to using AllocMem() which had 16 hits. My focus isn't on the merits of using AllocMem() instead of GetMem() and FillChar() pair; what I do notice is the fact that in a lot of places there is a strong need for zeroed memory. That brings me to the idea of handling the zeroing of memory chunks by the memory manager (MM) instead of doing it in-line.

A similiar idea has been discussed already here:

Besides this, it is pretty simple: give it a try and provide a patch.

Reply by email

Sven Barth
to Adem: I did a global search on trunk\compiler and found the following numbers: GetMem(): 212…
Adem wrote 5 lines
I did a global search on trunk\compiler and found the following numbers: GetMem(): 212 hits FillChar(): 362 hits

[...]

Show quoted text 11 lines
--------------- More hit data: fpc/trunk/packages/ GetMem(): 1464 hits FillChar(): 608 hits trunk/lazarus/ GetMem(): 522 hits FillChar(): 1366 hits

You might also search in rtl/ (especially objpas), because that contains the core of FPC's class system (and almost everything passes through that code some time).

You might also try a proof of concept implementation of your idea to demonstrate whether there really is a benefit (you can replace the default memory manager, so you should be able to test this without touching the current default heap manager).

Regards,
Sven

Reply by email