单声道下的堆栈大小

Joe*_*uha 10 .net mono recursion f#

我编写了一个很小的递归F#代码来查看我可以在.NET/Mono下的堆栈中放入多少级别的递归.它只是在精确的2次幂时打印递归深度,所以我发现最大深度在2的范围内.

我在一个具有定义的堆栈空间量的线程中启动代码System.Threading.Thread (ThreadStart, int).在.Net下,每个递归级别似乎需要大约100个字节,而我可以在2G堆栈上获得大约1600万个级别.Mono下的内存使用情况大致相似,但是我只能获得大约3万个级别.增加传递给Thread过去的堆栈大小值600000不会增加递归深度.

ulimit 报告堆栈大小限制为1G.

一个明显的解释是Mono不会服从第二个论点,Thread如果它太大了.有没有人知道如何说服Mono分配一个大堆栈?

代码是微不足道的,但它只是在某些人关心的情况下:

let rec f i =
    if popcount i = 1 then // population count is one on exact powers of 2
        printf "Got up to %d\n" i
        stdout.Flush ()
    if i = 1000000000 then 0 else 1 + f (i+1)
Run Code Online (Sandbox Code Playgroud)

chu*_*e x 8

选项1:更改单声道堆栈大小

一个明显的解释是Mono不会服从第二个论点,Thread如果它太大了.有没有人知道如何说服Mono分配一个大堆栈?

你是正确的Mono将限制堆栈大小,即使你传入一个大的值.例如,在我的Cent OS 64位测试机器上,Mono将分配的最大堆栈大小为2兆字节.该单C#源文件Thread.cs告诉我们,当你创建一个会发生什么螺纹:

public Thread (ThreadStart start, int maxStackSize)
{
    if (start == null)
        throw new ArgumentNullException ("start");

    threadstart = start;
    Internal.stack_size = CheckStackSize (maxStackSize);
}

static int CheckStackSize (int maxStackSize)
{
    if (maxStackSize < 0)
        throw new ArgumentOutOfRangeException ("less than zero", "maxStackSize");

    if (maxStackSize < 131072) // make sure stack is at least 128k big
        return 131072;

    int page_size = Environment.GetPageSize ();

    if ((maxStackSize % page_size) != 0) // round up to a divisible of page size
        maxStackSize = (maxStackSize / (page_size - 1)) * page_size;

    int default_stack_size = (IntPtr.Size / 4) * 1024 * 1024; // from wthreads.c
    if (maxStackSize > default_stack_size)
        return default_stack_size;

    return maxStackSize; 
}

上面的代码对堆栈大小设置了硬性限制.

理论上,您可以在上述一个或两个函数(粗线)中更改代码,以便分配更大的堆栈大小.完成此操作后,您必须构建Mono运行时,然后运行您的函数以查看更改是否有所不同.

我应该强调一点,我对Mono不太了解,了解分配更大的堆栈是否有助于您的具体情况.我只会这样做作为最后的手段(如果我的其他答案都不起作用).