日本ソフトウェア科学会第 31 回大会 (2014 年度) 講演論文集

高レベル LLVM マクロとしての MetaOCaml
高島 尚希

オレッグ・キセリョーヴ

亀山 幸義

MetaOCaml は型安全なメタプログラミングを実現する OCaml の拡張であり，コードの生成や変換を高レベルな記述で行なうことができるという特徴がある．一方，LLVM はコンパイラインフラストラクチャであり，低レベルな記述言語を用いて，最適化されたコードを生成できる．本研究は，MetaOCaml プログラムが生成するコードを LLVMコードに変換する変換器を設計・実装した．これにより，MetaOCaml を用いて，容易に LLVM コードを生成することができるようになる．本研究で提案する手法は，LLVM コードを直接生成する場合と比較して，型システムによる安全性が保証される点で優位である．また，生成された OCaml コードをそのまま OCaml のランタイムで実行する場合と比較して，LLVM が持つ最適化パスを利用できる点，LLVM のベクトル化命令を含むコードを生成することで高い実行性能を得ることができる点で優位である．

た低レベル最適化を系統的に行える可能性があるこ

1 はじめにとが実証された。一方で、OCaml や Scala のようにメMetaOCaml は，型安全なメタプログラミングを実モリ管理を言語処理系が行なう言語は、数値計算の性現する OCaml の拡張であり，コードの生成や変換を能について、C 言語等に及ばないという問題がある。

高レベルな記述で行なうことができる [1] [2]。コード生

これにより、たとえば、複数のコード生成を行い、テ成を支援する機構を持つ言語としては、Lisp/Scheme

スト実行を行ってその実行性能により最適コードを選(quasi-quotation), C++ template, template Haskell, Scala択するというタイプのコード生成法を、MetaOCaml

LMS などがあり，個々の対象ドメインの最適化を等で再現するのは困難である。また、高性能を得るた組みこんだコード生成器を記述することができる．

めには、最近の Intel プロセッサに見られるベクトル

MetaOCaml の特徴は，一定の範囲で (副作用等がない化命令などを活用する必要があるが、これも OCaml

部分言語に対して) 型安全性が静的に保証される点でコンパイラを利用して直接利用するのは困難である。

あり，これにより，生成されたコードの誤りをコード

これらの問題を解決するためには、低レベル言語で記生成前に発見することが可能になる．以下では，コー述されたコードを直接生成することが必要である。

ド生成を支援する機構を持つ言語をステージ化言語

このような背景に基づき、本研究は、MetaOCamlと呼ぶ．

で生成した OCaml コードを、低レベル言語の 1 つで

湘 南 チャレ ン ジ (Shonan Challenge for Generative

ある LLVM のコードに変換するプログラムを設計・Programming) [3] は，ステージ化言語を高性能計算に実装することを目的とする。LLVM は、低レベルの適用する試みである。この試みにより、高レベルのプ仮想機械に対するコンパイラ基盤であり、多数の最ログラム言語を用いて，メモリへの転送効率等を考え適化を組み込んで高い性能をあげることに成功していることから、広く使われるようになっている。特MetaOCaml as High-level LLVM Macro
Naoki Takashima, Oleg Kiselyov, Yukiyoshi Kameyama, 筑波大学コンピュータサイエンス専攻, Department of Computer Science, University of Tsukuba.に、Intel プロセッサのベクトル化命令等にも対応しており高性能計算を表現することが可能である。本研究では、数値計算を中心とした高性能計算の高性能コード生成にターゲットを絞り、このようなコー分方程式などに関する問題と，それらに対する最適ドを記述するのに必要十分な OCaml のサブセットか化の記述を公開している．ここでいう最適化は，高性ら、対応する LLVM のコードを生成するシステムを能計算において最大の問題となるメモリのレイテン作成した。また、このサブセットに、ベクトル命令なシを考慮した低レベルの最適化である．湘南チャレ

ど OCaml に存在しないプリミティブを追加し、変換ンジへの参加者は，ステージ化言語を用いて，個々のを拡張することにより、ベクトル命令を明示的にも問題対して最適化を実現するコードを生成するプロ

つ LLVM コードを生成した。得られた LLVM コード

グラム (コード生成器) を解として作成して投稿する．

は、LLVM 基盤により最適化を施されてコンパイル

その後，Shonan Challenge の初期の問題の多くに対しされ実行される。て，その解が MetaOCaml や Scala LMS のプログラム

先行研究としては、Eckhardt らによる研究があるとして与えられている。これらのプログラムで生成さ[4]。彼らは、MetaOCaml で生成された OCaml コードれたコードは、対応する最適化を組みこんだ C プロを C 言語のコードに変換しており、手法は類似してグラムとほぼ対応するものである。

いるが、生成する対象が異なる。Mainland の研究は、この経験から得られた知見の 1 つは，高レベルのtemplate Haskell を用いて C や CUDA のコードを直接プログラム言語を用いて，メモリ効率を考えた低レ生成するものであり、C などの対象言語に合わせた型ベル最適化を系統的に行える可能性があることが実システムを独自に構築している点、また、型安全性が証されたことである．低レベルの最適化は，従来は，静的に保証されない点が、本研究とは異なる [5]。

高性能計算の専門家による技芸によるところが多かっ

本研究の成果により、メモリアクセスのレイテンシたが，高レベル言語の持つ抽象化機構 (型，高階関数，やベクトル化命令のような低レベルの最適化を含むコントロール，モジュールなど) を利用して，より系コード生成器を MetaOCaml で記述して、直接コード統的に，低レベル最適化を行なうことができる可能性生成できるようになる。見方を換えれば、LLVM コーが開けたことになる。

ドを生成するマクロ言語として MetaOCaml を使うこ

一方で、生成されるコードが OCaml 等で記述さとができ、OCaml の豊富な抽象化機構を用いた系統れていることによる問題があらためて認識された。

的で保守性の高いマクロを記述できるようになるこ

OCaml などメモリ管理を言語処理系が行なう場合、とが期待できる。

数値計算の性能については、C 言語等の低レベル言語 (メモリ管理をプログラマが行なう言語) には及ば2 背景と準備ない。このため、高性能計算で使うためには、生成

2. 1 研究の背景した OCaml コードを、対応する低レベル言語のコー

プ ロ グ ラ ム に よ り プ ロ グ ラ ム (コ ー ド) を 生 成ドに書き直す必要があるが、問題はそれに留まらなす る と い う 研 究 は 、Lisp の 擬 似 引 用 (quasi quo-い。複数のコード生成を行い、テスト実行を行って最tation) に 始 ま り、現 在 で は ，C++ template, Tem-

適コードを選択するというタイプのコード生成法を、

plate Haskell, Scala LMS (lightweight modular staging),

MetaOCaml 等で実現するのが困難であるという問題

MetaML, MetaOCaml など、本格的なプログラミングがある。また、高性能を得るためには、最近の Intel言語が実現されている。

プロセッサに見られるベクトル化命令などを活用するステージ化言語の実装が成熟し，いろいろな分野へ必要があるが、これも OCaml コンパイラを利用しての応用が始まっている．2012 年に始まった湘南チャ直接利用するのは困難である。これらの問題を解決す

レンジ [3] は，高性能計算の分野に的を絞り，従来，るためには、低レベル言語のコードを直接生成する必手動で行われてきた様々な最適化コードの生成を，ス

要がある。

テージ化言語により系統的に行なうことを目的とした試みであり，行列計算，隠れマルコフモデル，偏微2. 2 MetaOCaml と LLVMている。また、多くの高性能計算においては、コー

MetaOCaml [1] は、OCaml 言語に quasi-quotation をド生成に要する時間がかかることは問題でないこと追加した形のステージ化言語であり、OCaml 言語のも、この選択を後押しする。これに対して、生成さ任意の式をコードとして生成できる点、2 段階だけでれたコードは、人手による修正を想定しない一方、はなく 3 段階以上の任意の段階のステージ化が可能

実行性能への要求は極めて厳しいので、低レベルプである点、静的な型システムを持ち、副作用のないサログラミング言語による記述が望ましい。これらのブ言語に対しては型安全性が保証されている点など観察により、図 1 に示したような、コード生成器とに特徴がある。当初の MetaOCaml は Walid Taha らに生成コードが異なるプログラミング言語で記述されより 2005 年頃にリリースされた。2010 年に著者らのる状況が最適という結論に至る。このようなコード一人である Oleg Kiselyov が完全な再実装として BER
MetaOCaml†1 を発表した。

生成は、heterogeneous なコード生成と呼ばれており、LLVM†2 は、低レベルの仮想機械に基づくコンパイラ基盤を提供するプロジェクトであり、このプロジェ

MetaOCaml のような、コード生成器と生成コードがほぼ同じプログラミング言語で記述される homogeneousなコード生成と対比される。

クトの成果物は、多様なプログラミング言語に対するMetaOCaml プログラムで LLVM コードを生成するコンパイラを提供すること、多くの最適化を組み込みという heterogeneous なコード生成を行なうためには、非常に高性能なコードを生成すること、等の特徴によ

以下の方法が考えられるが、どちらも問題がある。

り、今日、広く使われるに至っている。
本研究では、LLVM を C 言語と同様のレベルの言語と見なして利用する。具体的には、メモリ管理や

1. MetaOCaml が、直接 LLVM コードを生成するよう、MetaOCaml を変更する。(Explicitly Het-erogenous MSP)

それに関する最適化、ベクトル化命令の挿入はプロ

2. MetaOCaml は OCaml コードを生成するが、生グラマが行い、レジスタ割当てやその他の最適化は成された OCaml から LLVM への変換器を用意す

LLVM 基盤に任せるという役割分担を想定し、前者る。(Implicitly Heterogenous MSP)

を MetaOCaml 等で制御する、という戦略を取る。

第 1 の方法は言語の型システムの再構築、型安全性の保証など多大な労力を必要とする。第 2 の方法

3 OCaml サブセットから LLVM への変換の実装は既に存在するが、OCaml フルセットに対す3. 1 異言語間のコード生成るコンパイラでは、ゴミ集めを考慮にいれた変換と我々の基本思想は、高性能を要する応用においてなるため、数値計算などに対する高性能は得られず、は、高レベルプログラムで低レベルプログラム (コード) を生成するべきである、というものである (図 1)。

本研究の目的は達成できない。
本研究は、第 2 の方法に基づくが、コード生成の対象を数値計算/高性能計算に限定することで、上記コード生成器高レベル言語で記述図1⇒

生成コードの問題を克服する。すなわち、数値計算/高性能計算低レベル言語で記述に特化した DSL(ドメイン特化言語) を定義し、このHeterogenous なコード生成

DSL に対する LLVM への変換を与える。この DSL は非常に限定された OCaml のサブセットと見なすこと

コード生成器の記述は、多数の最適化の組み合わができるものであり、なおかつ、C 言語等の手続き型せや複雑なコントロールを必要とするため、型、モ言語のサブセットとも見なせるものである。(次節でジュール、高階関数、コントロール抽象など様々な抽見るように、この DSL は、for, while, 変数や配列への象化機構を持つ高レベルプログラミング言語が適し代入といったプリミティブから構成されている。) そ†1 http://okmij.org/ftp/ML/MetaOCaml.html†2 http://llvm.org

こで、この DSL から LLVM への変換はほぼ自明となり、性能を落とすことのない変換が可能となる (図 2)

コード生成器

p ::= fun x · · · x -> e

MetaOCamle ::= c | x | let x = e in e | e; e↓⇒

生成コードDSL(OCaml)
図2

変換後のコードLLVM

本研究のアプローチ

DSL (OCaml サブセット) から、LLVM や C への変|e+e|e-e|e*e|e/e| e +. e | e -. e | e *. e | e /. e| e < e | e > e | e <= e | e >= e | e = e | e <> e| ref e | ! e | e := e| e.(e) | <- e

換が「ほぼ自明」であるのは、欠点ではなく、本研究| float e | float of int e | int of float eの主張点である。すなわち、DSL と、それを変換し| while e do e done | if e then e else e

た LLVM コードがほぼ同じものであることから、変換の正しさについての疑問を少なくし†3 、LLVM コ| for x = e to e do e done| for x = e downto e do e done

ンパイラ内部で行われる最適化以外の全ての最適化をMetaOCaml のレベルで行なう (DSL から LLVM への

図3

変換対象の DSL の構文変換では一切の最適化を行わない) という役割分担を明確にする。

お、必要に応じて、図 3 であげたもの以外の構文に本研究で提案する手法は，MetaOCaml や OCaml でも対応できるよう適宜拡張している。たとえば、2 次記述されたプログラムにより、LLVM コードを文字元配列は BigArray を使って表現し、ベクトル命令を列として直接生成する場合と比較して，型システムに生成する際には対応するプリミティブを上記 DSL による安全性が保証される点で優位である．また，生成追加している。

された OCaml コードをそのまま OCaml のランタイ

上記の DSL は OCaml のサブセットであるため、そムで実行する場合と比較して，LLVM が持つ最適化の意味論は、OCaml の意味論と同様に定める。ただパスを利用できる点，LLVM のベクトル化命令を含し、基本型の値に関しては OCaml とは異なり、以下むコードを生成することで高い実行性能を得ることの通りとする。

ができる点で優位である．

• int, bool, unit 型は OCaml のそれではなく、LLVMの i64 型 (64bit 整数型) と解釈する。

3. 2 対象言語• float 型は LLVM の double 型と解釈する。

図 3 は、本研究が対象とする DSL (OCaml サブセッ

このため、上記の DSL で記述されたプログラムをト) の主な構文を示したものである。ここで、c は、OCaml 内で実行するときは、直接実行するのではな整数もしくは浮動小数点数の定数であり、x は変数をく、LLVM の i64 型や double 型であることを反映し表す。

たインタープリタによる処理を行わなければならな変換対象となる式 p は (一階の) 関数である。このい。これは実行性能を著しく落とすことになるが、上関数の本体 e の構文は上記のように手続き型言語に記 DSL の OCaml 内での実行は、テスト目的のみで相当する構文を組み合わせたものである。この DSL行われるため、特に問題は生じない。

で使えるデータ型は、int, double, bool, unit 型、およびそれらの配列型であり、高階関数や多相型は利用で

3. 3 対象言語から LLVM への変換きない。これらの制約のもとで OCaml で型付けでき

上記 DSL から LLVM への変換について述べる。

るプログラムが、上記 DSL のプログラムである。な

我々の基本方針を反映して、上記 DSL は C 言語風†3 異なる言語間の変換の正しさは、通常、定理証明支援系等による手間のかかる検証を要する。の while 言語の小さなものであるので、for, whilte,if-then-else などの構文を LLVM のコードに対応付け

.<fun m v1 v2 row ->; ModuleID = ’code’

let sum = ref 0.0 in
define i64 @code(double*, double*, double*, i64) {...
body4:; preds = %cond3
sum := 0.0;
%15 = load double* %4
for j = 0 to column - 1 do
%16 = load i64* %9
sum := !sum +. m.(i*column+j) *. v1.(j) %17 = mul i64 %16, 10000%18 = load i64* %12
done;%19 = add i64 %17, %18v2.(i) <- !sum
%20 = getelementptr double* %0, i64 %19%21 = load double* %20
done%22 = load i64* %12>.
%23 = getelementptr double* %1, i64 %22%24 = load double* %23
図 4 行列とベクトルの積のコード%25 = fmul double %21, %24%26 = fadd double %15, %25
store double %26, double* %4るための標準的方法を採用することにより、DSL の%27 = load i64* %12
抽象構文から LLVM コードへの変換が自然に定義で%28 = add i64 %27, 1きる。変換の詳細はここでは省略する。
store i64 %28, i64* %12
br label %cond3
図 4 は、MetaOCaml で生成されたコードの例で...

for i = 0 to row - 1 doある。
ここで、.< ...>. は、brackets と呼ばれ、コード

図5

本システムが生成した LLVM コードの一部 (最適化前)であることを表す MetaOCaml の構文である。bracketsの中身が前節で述べた DSL のプログラムである。ここでは、行列 m、ベクトル v1 および行方向のサイズを受け取り (列方向のサイズは静的に column という変数に格納されているとする)、m と v1 の積をベクトル v2 で返す関数を表している。
本研究の変換システムは、この OCaml コード†4 をLLVM コードに変換する。図 4 の OCaml コードを変換すると、図 5 に示す LLVM のコードが得られる。
これに対して、LLVM の最適化を適用することにより、図 6 に示す LLVM コードが得られ、LLVM のツールにより機械語へとコンパイルされる。

; ModuleID = ’code’
define i64 @code(double*, double*, double*, i64) {...
body4:; preds = %cond3%12 = mul i64 %11, 10000%13 = add i64 %12, %9%14 = getelementptr double* %0, i64 %13%15 = load double* %14, align 8%16 = getelementptr double* %1, i64 %9%17 = load double* %16, align 8%18 = fmul double %15, %17%19 = fadd double %.0, %18%20 = add i64 %9, 1
br label %cond3...

ここで生成したコードは、関数 1 つ分に相当し、C言語等で記述されたメイン関数とリンクすることに

図6

本システムが生成した LLVM コードの一部 (最適化後)より、実行可能なコードとなる。

3. 4 ベクトル命令の生成
ベクトル命令とは、複数の値をベクトル状に並べ、それらの値に対する演算 (加算や乗算など) を 1 つの命令で同時に行なうものであり、多数のデータに対し†4 Brackets を含めれば、MetaOCaml コードと呼ぶべきだが、brackets 等の MetaOCaml に関する処理は何もせず、brackets の入れ子等も許さないため、ここではOCaml コードと呼ぶことにする。て同じ演算をほどこす場合に高い性能を得ることができる。本研究では、Intel や AMD の CPU で利用できる SSE2 や AVX のベクトル命令を含むコードの生成を行った。

let array_to_d4 pd a ind =このため、本研究での変換対象を定める DSL に、

let rec visit pd i =4 つの float 型 (LLVM の double 型) の値をパックにしif i >= 4 then pd

た Double4 というデータ型を追加し、これらに対す

else

る操作のための以下の関数を持つ Double4 モジュー

visit .<Double4.insert (.~pd)(.~a).(.~ind + i) i>. (i+1)

ルを定義した。

make: 定数要素から Double4 型のデータを構築する;;

extract: Double4 型のデータから要素を取り出す

let code =

insert: Double4 型のデータの一部を書き換たデー.<fun m v1 v2 row ->タを作る。

let pd0 = (Double4.make 0. 0. 0. 0.) in

add, sub, mul, div: Double4 型データへ演算を

for i = 0 to row - 1 do行なう。

let rpd0 = ref pd0 infor j = 0 to cc - 1 do

図 7 は、ベクトル化命令を使って行列とベクトルの積の計算を記述したコード生成器の例である。

let pdv1 = .~(array_to_d4 .<pd0>. .<m>.

Double4.make により要素が 0.0 であるベクトルを作.<i * column + j * 4>.) in

成し、Double4.add により、ベクトル型のすべての要

let pdv2 = .~(array_to_d4 .<pd0>. .<v1>.
.<j * 4>.) in

素に対する加算を一気に実現している。 array_to_d4

rpd0 := Double4.add !rpd0

は、第 2 引数の配列 m における第 3 引数のインデッ(Double4.mul pdv1 pdv2)

クスの場所から 4 つのデータにより、ベクトル型のdone;データを構成する関数である。これらは、コード生成段階で動く関数であり、これを MetaOCaml という高...

度な抽象化機能を持つ関数で記述することにより、コ>.

ンパクトで見通しのよいコード生成器を記述するこ

図7

ベクトル化命令を使ったコード生成器 (一部)とができる。
本システムでは、ベクトル型に対する命令を含むOCaml コードを、対応する LLVM コードに変換できるようにした。この LLVM コードを、ハードウェア(CPU) の機能に応じて、SSE2 や AVX 対応命令にコンパイルすることにより、ベクトル化命令の恩恵を受けた高い性能を獲得することができる。

あたっては OCaml を用い、システム全体は 600 行程度である。
本システムの主なコンポーネントは以下のものである。

• MetaOCaml が生成した型推論済みの抽象構文木(Typedtree) から、本研究で必要な情報を抽出した構文木に変換する部分。

4 実装と性能評価
4. 1 実装について• 上記の構文木を LLVM のコードに変換する部分。
後者の変換部分は、本研究の方針通り「ほぼ自明」

本システムは、MetaOCaml (BER MetaOcaml バーになるものであり、LLVM コード生成についての知ジョン N101, OCaml 4.0.1 の拡張) で生成されたコー識を前提とすれば、実装もさほど難しいものではな

ドを、LLVM のビットコードに変換する。その後、かった。

LLVM を利用して最適化・コンパイルを行なう。利用した LLVM は LLVM 3.4.1 である†5 . 変換器の実装に一方、前者は、概念的には単純なもののはずであるが、今回の研究で最も苦労した点である。すなわ†5 テストのために、メイン関数を C 言語で記述してコンパイル・リンクする必要があるが、これには LLVM

ソフトウェアに含まれている clang を利用した。

ち、OCaml (およびそれのスーパーセットとしての内積行列・ベクトル積

OCaml(byte code)

21070

OCaml(native code)

22070

LLVM 変換 (ベクトル化なし)

2.73

1.10

LLVM 変換 (ベクトル化あり)

2.40

0.99

MetaOCaml) は高度な型システムを持っており、その型推論が終わった後の抽象構文木は、極めて複雑な構文をもっており、かつ、冗長な情報が多数含まれている。一例として、fun x -> x という単純なコードでも、その型推論後の抽象構文木は、100 以上のサイズを持つ巨大なデータとなる。また、OCaml の型推論

表1

内積計算プログラムの性能評価 (単位 秒)

器は的確なドキュメントが残されておらず、解読が容易でないことがよく知られている。本研究では、たとメイン関数において gerusage 関数を使って user time

えば、「この変数が int 型かどうか」といった判断を(マイクロ秒単位) を測定し、小数点以下第 3 位以下をする必要があるが、型の同一性の判定ですら単純では四捨五入した。

なく、OCaml/MetaOCaml システムの型推論器がもつ単一化関数に頼る必要があった。

表 1 にその性能測定結果を示す。ここで、内積プログラムは、長さ 10000 のベクトルの内積の計算を本研究では、共著者の知識をもとに、これらの問題30000 回繰返すプログラムである。行列・ベクトル積を乗り越え、現実の MetaOCaml システムと接続しては、行と列の長さが共に 10000 の行列と長さ 10000動くシステムとするためのシステム構築を行った。のベクトルの乗算を 10 回繰返したものである。
ベクトル化命令としては、SSE2, SSE3, AVX のす

4. 2 性能評価についてべてを生成して実行したが、今回の実験の範囲では実本システムの性能について、内積や行列とベクト行時間にほとんど差がなかったため、SSE2 での実行ルの積などのプログラムに関する予備的な性能評価を行った。ベクトルや行列の各要素は float 型 (double型に変換される) である。

結果を示した。
表 1 の結果から、今回のテストで利用した数値計算の領域では、OCaml (あるいは MetaOCaml) 内でのこれに対して、素朴に実装したコードを OCaml で実行に比べて、それを LLVM に変換して実行するこ直接実行したもの、それを本システムで変換して実とにより、劇的な性能向上が得られることがわかり、行したもの (ベクトル化命令なし、ベクトル化命令あ

本研究の手法が有効であると考えられる。

り) などのケースで実行速度を測定した。なお、コー

また、ベクトル命令について、今回は非常に単純なド生成時間は厳密には測定していないが、どのケース形で利用しただけであるが、それでも、一定の性能向も 10 秒以内に終了した。

上効果が得られることがわかる。今回のような、限定実験に使った計算機の仕様は、OS: Debian/Linux的な数のプログラムによる性能測定だけでは、決定的

wheezy (64bit OS), CPU Intel Xeon E31225, 3.10GHz,な結論を導くことはできないが、巨大な行列の乗算

Cache: 6MB, Main Memory 4GB であり、利用したソなど複雑な例題 (特に算術演算を多く必要とするコー

フトウェアは、MetaOCaml N101 (OCaml 4.01.0 ベース), LLVM 3.5.0svn, gcc 4.7.2†6 である。llc (LLVM のド) では、ベクトル命令の恩恵はより大きくなると予コード生成プログラム) および gcc には最適化オプショ

なお、ベクトル命令を利用する改変したコード (図ンとして -O=3 を指定した。時間の測定は、OCam-7) は、一種の loop unrolling の結果と考えることもで

l/MetaOCaml 内での測定では Unix.time 関数を使いき、人手で直接記述するよりも、MetaOCaml などの(秒単位での測定)、LLVM 変換後のコードは C 言語のコード生成言語を用いて生成すべきであると考えら†6 gcc は、本研究の C 言語のメイン関数をコンパイルし、本システムにより生成されたプログラムとリンクするためにのみ用いた。

想される。

れる。特に、高性能数値計算において利用されるタイリングやステンシル計算などの技法と合わせてベクトル命令を組み合わせて利用する場合には、極めて繁雑なコードとなり間違いやすくなるため、高レベルという大きな問題について迫っていくとを今後の課題

プログラミング言語による抽象度の高いコード生成とする。

が必須である。本研究は、そのような応用において、より有効となると考えている。

謝辞 本研究にあたり、プログラム論理研究室の小堀育男君と須永修平君にはテスト等で大変お世話になったので記して感謝する。

5 まとめ
本論文では、数値計算を中心とした高性能計算のコード生成を、MetaOCaml による高レベルプログラ参考文献ミングで行なう、という考え方に基づき、これを支[1] Walid Taha. A gentle introduction to multi-stage programming. In Domain-Specific Program Generation, pp.
30–50, 2003.
[2] Oleg Kiselyov. The design and implementation of BER
MetaOCaml - system description. In FLOPS, pp. 86–102,
2014.
[3] Baris Aktemur, Yukiyoshi Kameyama, Oleg Kiselyov,
and Chung-chieh Shan. Shonan challenge for generative
programming: Short position paper. In Proceedings ofthe ACM SIGPLAN 2013 Workshop on Partial Evaluation
and Program Manipulation, PEPM ’13, pp. 147–154, NewYork, NY, USA, 2013. ACM.
[4] Jason Eckhardt, Roumen Kaiabachev, Emir Pasalic,Kedar N. Swadi, and Walid Taha. Implicitly heterogeneous
multi-stage programming. In GPCE, pp. 275–292, 2005.
[5] Geoffrey Mainland. Explicitly heterogeneous metaprogramming with MetaHaskell. In Proceedings of the 17th
ACM SIGPLAN International Conference on Functional
Programming, ICFP ’12, pp. 311–322, New York, NY,USA, 2012. ACM.

援するシステムを設計・実装した。このシステムは、

MetaOCaml で生成された OCaml コード (数値計算に特化したもの) を、LLVM コードに変換するものであり、LLVM コンパイラの最適化の恩恵を受けて、非常に高い性能を発揮するコードを生成することができる。また、本システムの対象を拡張して、Intel CPUのベクトル化命令のうち Double4 に対応した命令を直接生成することもできるようにした。実験の結果、これらの戦略は、高性能計算コードを生成するのに有意義であるという基礎的データが得られた。
現時点では、まだ。実例の作成による実験データの蓄積が不足しており、この点については、今後の研究で取り組みたい。さらに、MetaOCaml での高レベルプログラミングによって、低レベルコード生成がどこまで的確に、かつ、系統的に行なうことができるか、