Mono中的尾调用优化

8
我有一些 F# 代码,这些代码在 .net 下运行得很好,但在 Mono 下会溢出堆栈。一个相关的问题是,在其所拥有的堆栈空间耗尽之前,它似乎早就已经发生了。该代码通过使用 System.Threading.Thread (ts, 1000000000) 启动。据我所知,它死在的 fold 函数是尾递归的,并且堆栈跟踪看起来好像没有进行尾-优化。我使用 --optimize=tailc 运行的版本是 3.2.1。

请问有人确切地知道哪些尾调用可以删除调用堆栈,哪些不能?或者有什么方法可以分配更多的堆栈?非常感谢。

我了解Mono中的尾调用消除

编辑:如评论中要求的那样,以下是代码概述。它是对一个大型数据结构的折叠的一部分,但失败的堆栈跟踪只包含 mapk 和 myfold 两个函数。

let rec myfold f x k =

   let rec mapk xs k =
    match xs with
     [] -> k []
   | x::xs -> mapk xs (fun xs' -> myfold f x (fun x' -> (x' :: xs') |> k))

... 

mapk (...) ( ... >> k)

你在哪个平台上运行Mono?(FreeBSD?OS X?Linux?) - Jack P.
Linux。如果这有所不同,那么是一台带有64G RAM的8核AMD机器。 - Joe Huha
你有什么样的尾递归函数?它是调用自身还是调用其他函数?(或者它使用continuations吗?)(我只是试图弄清楚可能出了什么问题 - 因为一些尾调用实际上被F#编译器优化掉了。) - Tomas Petricek
1个回答

1
据我所知,--optimize=tailc 不是受支持的 F# 编译器标志。
我认为没有办法在 Mono 中启用/禁用尾调用优化支持(无论从命令行还是其他方式);启用尾调用优化的 F# 编译器标志是 --tailcalls+,但根据 Compiler Options (F#),它默认已启用。
我认为您解决这个问题的最佳选择是:

Tailc是Mono的“优化”选项。我在运行F#时使用--tailcalls。我怀疑提交错误报告会适得其反,因为众所周知Mono在尾调用方面并不完全正确(或者直到最近)。但如果有人确切地知道现有支持何时起作用,何时不起作用,那将是很大的帮助。 - Joe Huha
3
如果你不报告错误,那么任何人都不会知道如何修复它。 - 7sharp9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接