Memory allocation purity

Adam Sakareassen via Digitalmars-d digitalmars-d at puremagic.com
Wed May 14 19:49:10 PDT 2014


For my 2 cents,

The more D allows 'pure' functions to diverge from functional purity the 
less relevant the flag is for compiler optimisations.

I think purity should be defined by what the compiler is allowed to do 
to a function.  The results of all pure functions should be cacheable. 
If the compiler can prove that the arguments to a pure function are 
constant then the function can be run at compile time to get the result.

A more advanced compiler should be able to do a lot of optimisation 
based on the fact that a function is marked pure.  A compiler can often 
prove arguments are constant when a human can't show the same easily. 
Other optimisation parses often expose constants that may be arguments 
to pure functions.

For example, a foreach loop over a small array could be unwound to 
remove the overhead of branching.  The iterator then becomes a constant 
in each segment of the former loop.  If the iterator is the argument to 
a pure function, the entire function call could be eliminated and 
replaced with the result.

By the same reasoning cacheability is important.  A pure function might 
be called within a loop with a parameter that is not altered during the 
loop.  If the compiler knows the function is pure, it can perform the 
calculation before the loop and simply reuse the cached result for each 
iteration.

New and malloc are not really pure.  They return a different result each 
call, and the state of the PC is changed.   However, if the programmer 
knows his function behaves in a pure way, it would be nice if a 
programmer could tell the compiler to go ahead and optimise away the 
function call anyway.  Some kind of “trusted pure” tag would be required 
I guess.

A 'trusted pure' function would be free to allocate memory as it wishes, 
providing it is freed (or left for collection), and the pointer does not 
escape the function.  From the point of view of the calling software the 
function is functionally pure.

My point is that if we are going to allow relaxed purity in D, then the 
definition should be angled towards a performance advantage.  Naturally 
there are quite a number of other advantages of creating pure functions 
besides performance.  If we define what compiler is allowed to do to a 
pure function we make reasoning about pure functions simple.  It even 
opens the idea of 'trusted pure' functions that compiler can't prove are 
pure, because they may do something like call a C routine.  From a 
compilers point of view they could be considered pure because the 
programmer says the compiler is free to eliminate the function call if 
it knows the result.


On 15/05/2014 8:42 AM, Brian Schott via Digitalmars-d wrote:
> What is the plan for the "pure"-ity of memory management?
>
> Right now the "new" operator is considered to be pure even though it is
> not, but related functinos like malloc, GC.addRange, GC.removeRange, and
> others are not.
>
> This prevents large portions of std.allocator from being pure. This then
> prevents any containers library built on std.allocator from being pure,
> which does the same for any funcions and data structures written using
> those containers.
>
> If malloc can never be considered pure, even when hidden behind an
> allocator, why can it be considered pure when hidden behind the GC?
>



More information about the Digitalmars-d mailing list