本文へ
ハクソク

世界を動かす技術を、日本語で。

ターボハスケル

元記事: 原文(comonad.com)

概要

  • THCは Haskell のための新しいJIT/AOTコンパイラ
  • GHC Core をJVM上で実行可能、GraalVM/Truffleを活用
  • Template Haskell や Linear Haskell など高度な機能を完全サポート
  • Polyglot FFI でPythonやJavaScript等の他言語ライブラリを利用可能
  • パフォーマンスや開発進捗、今後の課題についても解説

THC: Turbo Haskell Compiler の概要

  • THC はEdward Kmettが開発した Turbo Haskell Compiler、Haskell向けJIT/AOTコンパイラ
  • GHC 9.14.1 のすべてのprim-opsを実装、GHC CoreをJVM上でJIT実行
  • Cadenza で開発した型付き関数型言語の実行手法を応用、TruffleとGraalVMを利用
  • GHC がパース・型検査・デシュガリング・Core最適化を担当、以降をTHCが実行
  • Template Haskell や Linear Haskell などの高度な言語機能も完全サポート
  • JITとしても、Native Imageによる AOTコンパイル にも対応、実行ファイル生成が可能
  • pandoc、 happy、 alex、 GHC自身 もJIT/AOTでコンパイル可能

パッケージ・FFI・他言語連携

  • Cabal によるパッケージ解決、複数ライブラリや Backpack にも完全対応
  • Polyglot FFI でPython、Ruby、R、JavaScriptのライブラリをHaskellから呼び出し可能
  • Data.Text とTruffle string間のFFI変換は、UTF-8エンコード時にゼロコピー
  • データフレーム、LLM、D3.jsビジュアライゼーション等の連携も容易
  • Quasi-quotation によるインラインの他言語バインディングも実装が容易
  • Haskellライブラリ内のC/C++コードは Sulong (JVM上のLLVM)経由で実行
    • ネイティブモードSulongが通常のforeign import経路、マネージドモードも利用可能

評価・並列処理

  • Truffle評価用に バイトコードベースJIT と ASTベースJIT の2種類のバックエンドをサポート
  • シングルスレッド・マルチスレッド両対応、後者では追加ロックを実装
  • GHCバイトコード(BCO)もサポート、GHCi生成コードも実行可能
  • throwTo、非同期例外、マスキング等も完全サポート
  • Java標準スレッド や Project Loom によるGHCスタイルのグリーンスレッドも提供
    • HECスタイルのランタイムエグゼキュータ でMVar等の軽量同期プリミティブを実現

SIMD・最適化

  • SIMDはGHC prim-opsベースで対応、さらに Vector API (jdk.incubator.vector)によるランタイム幅選択も可能
  • ループJITコンパイルで効率的なSIMD処理を実現

尾再帰最適化・スタック管理

  • ホットな尾再帰呼び出し はループ変換、通常呼び出し時はスタックフレームを定期的に巻き戻し
  • 64ビットBloomフィルタで再帰的な尾再帰呼び出しを検出、ヒット時はスローパス例外で継続を接続
  • Truffleノードをカスタム実装し、関数間ループ変換を実現
  • JVMの関数ボディ制限に達した場合は一時的にスタックフレームをリークし、後で回収
  • CHICKEN Scheme のGC戦略を参考に、蓄積したフレームの圧縮も実装

パフォーマンス・メモリ

  • Compressed oops (32ビットヒープ参照)でメモリ効率向上、最大ヒープ約32GB(JVM 8バイトアライメント時)
  • 開発初期のパフォーマンスはGHC比で概ね10〜20%遅いが、最速で3倍速、最遅で3倍遅い範囲
  • カバレッジ拡大時に一部ベンチマークで10倍程度の性能低下発生、継続的に最適化中
  • 非尾再帰パスでのスタック成長がGHC同等に抑えられているかは今後の課題

開発状況・参加方法

  • GitHub: github.com/ekmett/thc にて公開、ビルド・実行・利用方法のドキュメントあり
  • IRC: irc.libera.chat の ##thc チャンネルで開発進行中、誰でも参加可能
  • Edward KmettによるRedditでのディスカッションも実施

提供: ハクソク · 要約更新:

AIによる日本語要約です。内容は原文とあわせてご確認ください。

Hacker Newsの議論を読む

Hackerたちの意見

FFIリストにJavaが入ってないのは変だね。JVMターゲットなのに。タイプミスか見落としかな?

└

FFIがJavaバイトコードに対してじゃなくて、"ネイティブ"だからだと思う。でも、もちろんTruffle言語としては"無料"のJava相互運用性があるよね。

└

JavaのFFIはできるけど、ちょっと面倒な感じだよね。必要に応じて少しやってるけど、今はポリグロット言語に集中してて、きれいに扱うためのフックは後回しにしてる。JavaのFFIについて話すと、「じゃあ、賢い奴、どうやってこのJavaクラス/インターフェースを君の言語で書いたコードで拡張するの?」って言われちゃうんだけど、正直、Java以外の言語には満足できる答えがなかったんだよね。でも、今はHaskellのData.TextをFFIバインディングフレームワークを通して渡せるようになって、向こう側では有効なTruffleStringとして現れるんだ。UTF-8で、ゼロコピーセマンティクスもあって、もし他のTruffle言語がUTF-8エンコードされたTruffleStringを渡すと、それがData.Textに展開されるんだよ。それと、いくつかの配列サポートがあれば、他の言語とも十分にやり取りできる感じだね。

ちょっと関係ないけど、Frege[0]を思い出したよ。JVM用のHaskell方言で、昔見つけてすごくかっこいいと思ったんだ。最近のコミットはあるけど、リリースは全部古いから、プロジェクトの状態がわからないな。[0] https://github.com/frege/frege

└

何年もFregueのこと考えてなかったな!昔、ロゴやちょっとした問題を手伝ったことがあるんだ。最新のコミットをチェックして、何が更新されてるか見てみるよ(依存関係だけじゃないといいな :))。

ターボパスカルみたいな感じ?

└

いや、青いTUI IDEじゃなくて、JVM上のHaskellだよ。作者がそのコンセプトを無駄にしちゃったね :|

└

名前の一部は、Haskellをパスカルと聞き間違える人が多いことへのジョークだったんだ。エドが数年前に教えてくれた。たしか、ZuriHacで、Googleチューリッヒの頃だったから、2016年くらいかな?

参考までに、この記事はRedditのディスカッションにリンクしてて、ここでのいくつかのコメントに対する回答があるよ。

└

便利だから、そのRedditスレッドを貼っておくね。

ポリグロットFFI機能(GraalVMのおかげ)は、「関数型コア、命令型シェル」スタイルのデザインを実装するのにすごく役立つかもしれないね。

偶然にも、著者がHaskell Interludeポッドキャストでインタビューを受けたばかりだよね。

Hacker Newsで議論の続きを見る