.net - Mono 下的堆栈大小

标签 .net recursion f# mono

我编写了一小段 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)

最佳答案

选项 1:更改 Mono 堆栈大小

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?

即使您传入一个很大的值,Mono 也会限制堆栈大小,这是正确的。例如,在我的 Cent OS 64 位测试机上,Mono 将分配的最大堆栈大小为 2 MB。 Mono C# source file Thread.cs向我们展示创建 Mono 线程时会发生什么:

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 的了解还不够,无法理解分配更大的堆栈是否对您的具体情况有帮助。我只会将其作为最后的手段(如果我的其他答案都不起作用)。

关于.net - Mono 下的堆栈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19817790/

相关文章:

f# - Deedle - 根据同一行另一列中另一个项目的值替换列中项目的最有效(最快)方法是什么

c# - 随机数生成器安全 : BCryptGenRandom vs RNGCryptoServiceProvider

.net - Azure 服务总线 - 更新锁定无法正常工作

c# - appname.vchost.exe 文件是什么

c# - 矢量化未提供预期的加速

javascript - 创建递归表单元素

java - 如何使用递归来简化重复的代码?

f# - 在 F# 中实现幻像类型

php - 对话的数据库逻辑(如论坛)PHP、MySql

F# CsvTypeProvider - 从推断类型映射函数