www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Trying to avoid the GC

reply Shachar Shemesh <shachar weka.io> writes:
I have a standard processing that needs to be done over and over again, 
with an inner function that is different between invocations. Here is a 
small sample that illustrates the need:

import std.stdio;

alias dtype = void delegate(int i);
void func(T)( T d )
{
     foreach(i; 0 .. 10) {
         d(i);
     }
}

int main()
{
     int sum;

     func( (int i) {
             sum+=i;
             });

     writeln(sum);

     return 0;
}

If you're wondering, "func" is templated in an attempt (unsuccessful) to 
prevent the problem I'm about to describe.

The problem is that despite both functions being in the same compilation 
unit and the fact it is obvious that the delegate passed to func is 
never used outside of the function, "main" cannot be declared  nogc 
(and, in particular, it allocates the frame for main on the heap). This 
is true also of gdc with -O3.

I've tried the exact same program with g++:

#include <iostream>

template <class T> void func( T d )
{
     for( int i=0; i<10; ++i ) {
         d(i);
     }
}

int main()
{
     int sum;

     func([&](int a) { sum+=a; });

     std::cout<<sum<<"\n";

     return 0;
}

This is almost a direct translation of the D program to C++11. Despite 
that, g++ (with -O3) figure out that func should be inlined, and then 
unrolls the loop, performs it at compile time, and replaces the entire 
program with:

std::cout<<45<<"\n";

For my purposes I do not need compile time evaluation (and D has the 
mechanisms to ensure those). What I do need is for it not to use GC to 
hold the function's frame when it's clear that that frame is never used 
outside of the function.

Failing that, I need an alternative way to wrap a changing action with 
constant loop without using GC controlled memory.

Thanks,
Shachar
Dec 31 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 31 December 2014 at 13:38:05 UTC, Shachar Shemesh 
wrote:
 alias dtype = void delegate(int i);
 void func(T)( T d )
Try writing that: void func(scope dtype d) instead. Or (scope T d) should do it too if you need it to be templated. The scope keyword tells the compiler that you promise not to escape it from that scope, so it is safe to use stack memory. Should prevent the copying to gc of a delegate. (One of the few places the scope keyword is actually implemented to do something!) Alternatively, an alias parameter to the template can take a predicate - assuming it is static - and generate a new function for each one. void func(alias pred)() { foreach(i; 0 .. 10) pred(i); } Then use it with func!(predicate)(). This is what Phobos std.algorithm uses. It can be trickier to actually make it work though. But scope should get you to the next step easily. gdc might even inline the delegate then, though I doubt dmd will. Even dmd ought not to GC with it tho.
Dec 31 2014
next sibling parent Shachar Shemesh <shachar weka.io> writes:
On 31/12/14 15:52, Adam D. Ruppe wrote:

 Try writing that:

 void func(scope dtype d)
Yep. That's exactly what I was looking for. On GDC it even allows for complete compile time evaluation of the entire loop. Thanks, Shachar
Dec 31 2014
prev sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wed, 31 Dec 2014 13:52:02 +0000
"Adam D. Ruppe via Digitalmars-d" <digitalmars-d puremagic.com> wrote:

 On Wednesday, 31 December 2014 at 13:38:05 UTC, Shachar Shemesh=20
 wrote:
 alias dtype =3D void delegate(int i);
 void func(T)( T d )
=20 =20 Try writing that: =20 void func(scope dtype d) =20 instead. Or (scope T d) should do it too if you need it to be=20 templated. The scope keyword tells the compiler that you promise=20 not to escape it from that scope, so it is safe to use stack=20 memory. Should prevent the copying to gc of a delegate. (One of=20 the few places the scope keyword is actually implemented to do=20 something!)
an it's so well hidden that not many people know about it. being a not very careful reader myself i discovered such `scope` usage while reading some code in another project and was a little puzzled.
Dec 31 2014
parent reply Shachar Shemesh <shachar weka.io> writes:
On 31/12/14 23:48, ketmar via Digitalmars-d wrote:
 On Wed, 31 Dec 2014 13:52:02 +0000
 "Adam D. Ruppe via Digitalmars-d" <digitalmars-d puremagic.com> wrote:
 Try writing that:

 void func(scope dtype d)
 an it's so well hidden that not many people know about it. being a not
 very careful reader myself i discovered such `scope` usage while
 reading some code in another project and was a little puzzled.
I've seen discussions here on whether scope should or should not go into specific versions, but have not been able to find anything more on what it actually means. Also, this brings me to a larger problem I have with the D documentation. I've read The D Programming Language (and even have a few entries at its errata), but when circling back to features I rely heavily on a good index, table of contents and internet searches to find precise syntax. And here D fails me. The keywords used are often too generic for a Google search. Add to that the fact that the language's name is a single letter, and you find yourself looking for "D is". Try it. The results are unhelpful. Searching for "dlang is" is somewhat better, but not much. TDPL's table of contents and index are also quite unhelpful (and the e-book version I have, from Safari books online, is a PDF with no hyperlinks). As a result, you are often left with no recourse but to ask someone who does know, or start leafing through the book hoping to find something. Which is a rather long way to say "I completely concur with ketmar" Shachar
Dec 31 2014
parent "Meta" <jared771 gmail.com> writes:
On Thursday, 1 January 2015 at 07:40:50 UTC, Shachar Shemesh 
wrote:
 Add to that the fact that the language's name is a single 
 letter, and you find yourself looking for "D is". Try it. The 
 results are unhelpful. Searching for "dlang is" is somewhat 
 better, but not much. TDPL's table of contents and index are 
 also quite unhelpful (and the e-book version I have, from 
 Safari books online, is a PDF with no hyperlinks).
Just as an aside, I find "d programming is expression" to be the most useful search string when I forget the various forms of `is`.
Jan 01 2015