10

Haskellでアルゴリズムのパズルを解こうとしています。そのためには、かなり大きなデータ構造が必要です。ただし、ソリューションを提出する問題解決サイトでは、実行時オプションを使用してスタックを大きくすることはありませんが、コンパイラオプションをプラグマとして使用できると聞いています。コードで次のプラグマを使用してみました。

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

次に、でコンパイルしghc --make algo.hsます。ただし、いくつかの大きなテストでマシンを実行すると、プログラムがスタックオーバーフローでクラッシュし、現在のスタックサイズが8MBであると報告されます。一方、私がそのようにコンパイルするとき:

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

+RTSプログラムは、引数を追加しなくても、同じデータで問題なく動作します。私はGHC7.0.2を使用していますが、問題解決サイトは6.12.3を使用しているので、できればその古いバージョンでも機能するソリューションを探しています。

4

1 に答える 1

10

ほとんどすべての種類のネイティブ バイナリのコンパイルは、少なくとも 2 つのステップで構成されることに注意してください: 実際のオブジェクトのコンパイル ( .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 にコマンド ライン処理の別のセットでリンクするように指示する)、オブジェクト ファイルをコンパイルするときに指定することはできません。リンク時に指定する必要があり、そのようなオプションはモジュールヘッダーには指定できません。

次の 2 つの解決策があります。

  1. Cabalを使用してビルドし、必要.cabalな GHC オプションをファイルに指定します。
  2. アルゴリズムを修正して、スタック スペースがそれほど必要とならないようにします。たとえば、末尾再帰を使用し、折り畳みをより厳格にします。詳細については、ウィキを参照してください。
于 2012-05-28T16:32:07.007 に答える