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