On Sunday, 7 February 2016 at 22:27:40 UTC, Joseph Rushton Wakeling wrote:
On Monday, 25 January 2016 at 22:06:31 UTC, Era Scarecrow wrote:
What you describe makes sense, but I don't quite follow what you mean in one particular case:

Technically alloca simply returns the current sp, then adds to it the number of bytes you requested. This means you have to run it at the function stack where you want to use it (and not in a called function, otherwise corruption). So inlined functions where alloca's data would remain would be a must.

That's the low level assembly language that's generated i'm referring to; At least based on what i've read and seen for code output from a compiler to a .s file or similar.

I don't quite follow your remark about inlined functions; do you mean that the function where the RNG instance is generated must be inlined? (That would make sense in order to avoid the internal state being deallocated immediately.)

Assuming alloca moves to the inlined function. Although i had another idea thrown in my head where the memory would be pre-allocated and you could just point to it when requested via an allocator. So assume

@alloca(sizeof(int)) struct RNG {

During instantiation it would know the size ahead of time and just append that to the end of the structure. That extra padding space could be handled manually instead.

 this(int seed) {
   state = cast(void*)(this+1);
 }

But this forced type breaking is quite clunky (and obviously the wrong way to write it).

I recall in C there was suppose to be a way to attach an array (of unknown size) immediately following a struct by making the length of the array 0, then accessing it directly. But you'd still need to guarantee somehow that the access rights are in place and not referencing other data which you could screw up (via optimizations or something).

I think there might be more complications here than just allocating individual RNG instances, though (which can happen quite early on in the program); what about stuff like random algorithms (RandomCover, RandomSample) which might be generated deep in internal loops, passed to other functionality as rvalues, etc. etc.?

Either they use more stack space, or they act normally after their call is done and are deallocated normally (automatically, unless they are passed outside of the scope where they were generated).

It might be simpler, in practice, to just have the state refcounted.

I suppose the alternate is an option to skip/throw-away some numbers that should've been consumed
I'm not sure I follow what you mean here or why you think this would work? Could you give a concrete example?

  void skip(int x) {assert(x>0); while(x--) popfront();}

rnd.take(10).writeln;  //loosely based on talk examples
rnd.skip(10);          //skips the 'consumed' numbers.
rnd.take(10).writeln;  //won't have identical output


I'm afraid that's not really viable :-(
But the problem is, in the general case, you can't anticipate how many random variates may be popped from your random number generator inside a function.

True; Perhaps have one RNG for seeding and one RNG for passing, then reseed after passing the function off, although how far deep some of this could go with it's deeper copying; I don't know.

Perhaps RNG should be a class outright, which probably removes a lot of these problems.

Reply via email to