Felix gc is now reasonably efficient. However,the world-stop at 
service call constraint plus some continued inefficiencies in the
optimisation process make some functional code impractical.


///////////////////////////////////////////////
//Check garbage collector
#import <flx.flxh>;
open List;
proc collect()
{
  println q"Before collection: nobj=$(gc_get_allocation_count()) amt=
$(gc_get_allocation_amt())";
  Control::collect();
  println q"After collection: nobj=$(gc_get_allocation_count()) amt=
$(gc_get_allocation_amt())";
}
collect();
var a = list(1,2,3,4);
fun conv (a:list[int])=>
  fold_left
    (fun (acc: list[int]) (item2:int)=>
      acc + map (fun (item1:int)=> item1+item2) a
    )
    Empty[int]
    a
;

var x = conv a;
Control::collect();
println q"x=$(x)";
collect();
x = conv x;
collect();
println q"x=$(x)";
collect();
/*
x = conv x;
collect();
println q"x=$(x)";
collect();
*/

var x_sum = fold_left (fun (acc:int) (item:int)=>acc+item) 0 x;
var y = map (fun (item:int)=> item * item) x;
var y_sum = fold_left (fun (acc:int) (item:int)=>acc+item) 0 y;

println q"x_sum=$x_sum, y_sum=$(y_sum)";
//////////////////////////////////////////////////////////////

This code throws my moronic Linux into a paging frenzy. I have
to say Linux sucks totally. I have swapoff, but it still pages.
The mouse doesn't move and I can't kill the process except with
a hardware reboot.

Anyhow, the problem in this code is that although the last 'conv()'
call generates a reasonably sized list, the fold/map functions also
spawn about 10 times more closures than the number of list elements.
The output:

//////////////////////
[EMAIL PROTECTED]:/work/felix/svn/felix/felix/trunk$ f
test/regress/nd-1.01.01-0.flx 
//Parsing Implementation std.flx
//Parsing Implementation test/regress/nd-1.01.01-0.flx
Before collection: nobj=4 amt=232
After collection: nobj=4 amt=232
x=[2, 3, 4, 5, 3, 4, 5, 6, 4, 5, 6, 7, 5, 6, 7, 8]
Before collection: nobj=150 amt=5752
After collection: nobj=24 amt=712
Before collection: nobj=9183 amt=429192
After collection: nobj=264 amt=6472
x=[4, 5, 6, 7, 5, 6, 7, 8, 6, 
........
6]
Before collection: nobj=2311 amt=88368
After collection: nobj=264 amt=6472
x_sum=2560, y_sum=26880
/////////////////////


264 elements, 0.5Meg Ram, the next pass blows 1G.
This test shows the GC works (and it seems fast).

However, functional code like this isn't practical because
the GC can't be called until the function terminates.

I can improve the optimiser .. the generated C++ is crap,
hardly any inlining and it didn't tail-rec optimise for 
unknown reason. But this will not solve the basic problem.

There's no way to run a non-world-stop collector.
Even a world stop single thread collector is hard because it
requires machine dependent finding of the machine stack
to scan for roots. 

There's also no way to actually stop threads that I know of
on Posix. [SIGSTOP stops processes .. I think this works on Linux, 
since a thread is a process]

Boehm has a number of platform dependent hacks to solve these things,
but there's no point emulating them: we might as well just use Boehm.

There IS a solution: get rid of functions. By that I mean forcibly
reduce all functions to procedural code. That eliminates the
machine stack. But it therefore gets in the way of calling Felix
functions inside C fun primitives, since such fragments do use
the machine stack.

Any suggestions on the way forward appreciated.. :)

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to