下单堆栈大小 [英] Stack size under Mono

查看:217
本文介绍了下单堆栈大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了F#code微小的递归位,看看有多少递归的水平,我可以适应到下.NET /单声道堆栈。它只是打印递归的深度时,它是2完全相同的力量,所以我找出最大深度内的一个因素2。

我开始code在一个线程中有定义使用 System.Threading.Thread(的ThreadStart,INT)堆栈空间量。在.NET下,似乎把每递归水平约100个​​字节,我可以得到一个2G的堆叠约1600万的水平。内存占用率下单声道大体相似,但是我只能得到大约30000水平。增加传递给过去超过约 600000堆栈大小值不增加递归深度。

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

这是显而易见的解释是,单不听从,如果它过大的第二个参数。是否有人请知道如何说服单声道分配一大叠?

在code是微不足道的,但它的下面,以防万一有人关心:

 让REC F I =
    如果popcount I = 1,则//人口数是在2确切的权力
        printf的起身到%d \ N我
        stdout.Flush()
    如果我= 10亿则0,否则,1 + F(I + 1)
 

解决方案

选项1:更改单堆栈大小

  

这是显而易见的解释是,单不听从,如果它过大的第二个参数。是否有人请知道如何说服单声道分配一大叠?

您是正确的,单将限制堆栈大小,即使你传递一个较大的值。例如,在我美分操作系统的64位试验机,即单将分配的最大堆栈大小为2兆字节。 Thread.cs 的单C#源文件,向我们展示当您创建的单声道的线程会发生什么:

公共线程(的ThreadStart开始,INT maxStackSize)
{
    如果(开始== NULL)
        抛出新ArgumentNullException(开始);

    的ThreadStart =启动;
     Internal.stack_size = CheckStackSize(maxStackSize); 
}

静态INT CheckStackSize(INT maxStackSize)
{
    如果(maxStackSize℃,)
        抛出新ArgumentOutOfRangeException(小于零,maxStackSize);

    如果(maxStackSize< 131072)//确保堆栈至少128K大
        返回131072;

    INT PAGE_SIZE = Environment.GetPageSize();

    如果((maxStackSize%PAGE_SIZE)!= 0)//一轮长达分割的页面大小
        maxStackSize =(maxStackSize /(PAGE_SIZE  -  1))* PAGE_SIZE;

    INT default_stack_size =(IntPtr.Size / 4)* 1024 * 1024; //从wthreads.c
    如果(maxStackSize> default_stack_size)
        返回default_stack_size;

    返回maxStackSize;
}

在code以上提出的硬性限制的堆栈大小。

您可以在一个以上的功能,或两者的理论变革code(粗体行),这样一个大的堆栈大小分配。一旦你这样做,你就必须建立在Mono运行,然后运行你的函数,看是否变化有差别。

我要强调的是,我不知道有足够的了解单声道理解,如果分配较大的堆栈将在特定的情况下帮助。我只会做这个作为最后的手段(如果没有我的其他的答案无效)。

I have written a tiny recursive bit of F# code to see how many levels of recursion I can fit onto the stack under .NET/Mono. It just prints the recursion depth whenever it is an exact power of 2, so I find out the maximum depth to within a factor 2.

I start the code in a thread with a defined amount of stack space using System.Threading.Thread (ThreadStart, int). Under .Net it seems to take approx 100 bytes per level of recursion, and I can get about 16 million levels on a 2G stack. The memory usage is broadly similar under Mono, however I can only get about 30 thousand levels. Increasing the stack size value passed to Thread past over about 600000 does not increase the recursion depth.

ulimit reports the stack size limit is 1G.

An obvious explanation is that Mono will not obey the second argument of Thread if it is too large. Does anybody please know how to convince Mono to allocate a large stack?

The code is trivial, but it's below just in case someone cares:

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)

解决方案

Option 1: Change Mono Stack Size

An obvious explanation is that Mono will not obey the second argument of Thread if it is too large. Does anybody please know how to convince Mono to allocate a large stack?

You are correct that Mono will limit the stack size, even if you pass in a large value. For example, on my Cent OS 64-bit test machine, the maximum stack size that Mono will allocate is 2 megabytes. The Mono C# source file Thread.cs shows us what happens when you create a Mono thread:

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; 
}

The code above puts a hard limit on the stack size.

You could in theory change code in one or both of the above functions (bold lines) so that a larger stack size is allocated. Once you did this you would have to build the Mono runtime and then run your function to see if the change makes a difference.

I should stress that I do not know enough about Mono to understand if allocating a larger stack will help in your specific case. I would only do this as a last resort (if neither of my other answers work).

这篇关于下单堆栈大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆