2012-05-28 66 views
9

我試圖解決Haskell中的算法難題,爲此我需要相當大的數據結構。然而,我提交解決方案的問題解決網站並未使用任何運行時選項來允許更大的堆棧,但我聽說我可以使用編譯器選項作爲雜注。我試過在我的代碼中使用下面的編譯指示:使用-with-rtsopts ghc選項作爲編譯指示

{-# OPTIONS_GHC -O2 -rtsopts -with-rtsopts=-K32m #-} 

然後我用ghc --make algo.hs進行編譯。但是,當我在我的機器上運行某些大型測試時,程序崩潰時出現堆棧溢出,並報告當前堆棧大小爲8MB。在另一方面,當我編譯這樣的:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp 

該項目工程在相同的數據就好了,不添加任何+RTS參數。我使用GHC 7.0.2,但解決問題的網站使用的是6.12.3,所以最好是我正在尋找可以使用該舊版本的解決方案。

回答

9

記住幾乎任何種類的本機二進制的彙編包括至少兩個步驟:實際對象彙編(.hs - >.o),和連接(.o.a.lib - >可執行/ .exe/.so/.dll等)

當您編譯如下:

ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp 

...什麼是真正幕後發生的事情基本上是:

# 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 

即, --make選項告訴GHC在鏈接結果之前自動編譯目標文件,並且它會爲您填充大量的空白。記下各個命令行標誌的最終位置。

當指定編譯在文件的頂部,這是不是發生了什麼(用ghc --make algo.hs):

ghc -c algo.hs -rtsopts -with-rtsopts=-K32M 
ghc -o algo -package somepackage algo.o 

OPTIONS_GHC編譯講述選項編譯器添加編譯時的那個特定模塊成目標文件。因爲-rtsopts是一個連接器選項(它告訴GHC鏈接在一組不同的命令行處理內容中),所以編譯目標文件時無法指定它。鏈接時必須指定它,並且這些選項不能在模塊標題中指定。

解決辦法有兩個:

  1. 使用Cabal建立的東西,爲您和您的.cabal文件中指定要
  2. 修復你的算法是什麼GHC選項,這樣你就不需要這麼多的堆棧空間例如通過使用尾遞歸和更嚴格的摺疊。有關更多信息,請參見the wiki