使用-with-rtsopts ghc选项作为pragma

fsh*_*fsh 9 stack-overflow haskell runtime pragma ghc

我正在尝试在Haskell中解决算法难题,为此我需要相当大的数据结构.但是问题解决网站我提交了我的解决方案,不使用任何运行时选项来允许更大的堆栈,但我听说我可以使用编译器选项作为pragma.我在我的代码中尝试使用以下编译指示:

{-# OPTIONS_GHC -O2 -rtsopts -with-rtsopts=-K32m #-}
Run Code Online (Sandbox Code Playgroud)

然后我编译ghc --make algo.hs.但是,当我在一些大型测试中运行我的机器时,程序崩溃并发生堆栈溢出,并报告当前堆栈大小为8MB.另一方面,当我编译时:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp
Run Code Online (Sandbox Code Playgroud)

该程序可以在相同的数据上正常工作,而无需添加任何+RTS参数.我使用的是GHC 7.0.2,但解决问题的网站使用的是6.12.3,所以我最好也在寻找可以使用旧版本的解决方案.

dfl*_*str 9

请记住,几乎任何种类的本机二进制的汇编包括至少两个步骤:实物汇编(.hs- > .o),和连接(.o,.a,.lib- >可执行/ .exe/ .so/ .dll等)

用这个编译时:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp
Run Code Online (Sandbox Code Playgroud)

......幕后实际发生的事情基本上是:

# object compilation - creates algo.o
ghc -c algo.hs -fforce-recomp
# linking - links together algo.o and libHSsomepackage.a into the "algo" binary
# (we assume that `algo.hs` included some module from the package `somepackage`
#  e.g. `Data.Package.Some`)
ghc -rtsopts -with-rtsopts=-K32M -o algo -package somepackage algo.o
Run Code Online (Sandbox Code Playgroud)

--make选项告诉GHC在链接结果之前自动编译目标文件,它会为你填充大量的空白.记下各个命令行标志的结束位置.

当您在文件顶部指定该pragma时,这就是发生的事情(with ghc --make algo.hs):

ghc -c algo.hs -rtsopts -with-rtsopts=-K32M
ghc -o algo -package somepackage algo.o
Run Code Online (Sandbox Code Playgroud)

OPTIONS_GHC编译指示告诉编译器在将特定模块编译到目标文件时要添加的选项.因为-rtsopts是一个链接器选项(它告诉GHC链接在一组不同的命令行处理内容中),所以在编译目标文件时不能指定它.您必须在链接时指定它,并且不能在模块标题中指定此类选项.

有两种解决方案:

  1. 使用Cabal为您构建内容并在.cabal文件中指定您想要的GHC选项
  2. 修复您的算法,以便您不需要那么多的堆栈空间,例如使用尾递归和折叠更严格.有关更多信息,请参阅维基.