情報処理学会研究報告
IPSJ SIG Technical Report

マルチ FPGA 向けシミュレーションコードの再利用性を改善するコード生成系の実装
福田 航生1,a)

池原 陽大1,b)

本吉 圭吾1,c) 眞邉 泰斗1,d)
佐野 健太郎2,g)

柴田 裕一郎1,e)

上野 知洋2,f)

概要：複数の FPGA から構成されるシステムの動作シミュレーションは，複数のモジュールを通信可能な状態で並列動作させる必要がある．しかし，既存ツールチェーンによるサポートは不十分で，そのようなシステムのシミュレーションには妥協が必要なのが現状である．
本研究の手法では，複数のモジュールの処理を単一のモジュール内で並列のタスクとして実行するように書き換える．これにより既存のツールチェーンを使用した動作シミュレーションが可能となる．
ソースコードをパースし，本手法を用いて単一のモジュールに統合したソースコードを生成する処理系の実装を行った．変換処理の時間はコンパイルを含む全体の処理時間の 0.3% 未満となった．
キーワード：リコンフィギュアラブルコンピューティング，並列アーキテクチャ，FPGA

1. はじめには並列に動作する多数の FPGA をネットワークを介して接続した構成をもち，それらが持つ再構成可能な領域を利近年のプロセッサの高集積化の鈍化や電力等の問題 [1], [2]用して所望のシステムを実現できる．ESSPER で動作するにより，HPC で現在主流であるメニーコアプロセッサをシステムはさまざまな手法での実装ができ，C++での動作多数接続するアーキテクチャでの性能向上が困難になっての記述からハードウェア合成を行う高位合成の使用も可能いる．また，メモリのバンド幅が性能のボトルネックになである．本研究ではこの方法について議論する．

る場合が多いという課題もある．一方，FPGA を使用した高位合成の強みの一つは，開発用のホストでソフトウェ計算では専用のハードウェアを構成することにより，チッア開発で用いられるような手法でシミュレーションするこ

プ上の資源を効率よく利用し，低消費電力で低遅延な処理とが可能な点である．ハードウェア用に記述されたソースを実現できる．さらに，ストリーム処理との相性がよいこ

コードは，ソフトウェア向けの実行ファイルとしてもコンとや，内蔵された SRAM は小容量であるものの高いバンパイル可能であり，テストベンチからハードウェア向けにド幅を提供することから，外部メモリのバンド幅が並列処記述したルーチンを呼び出し，シミュレーションを実行で理のボトルネックになりにくい．こうした理由から，HPCきる．ESSPER において，C++記述からのハードウェアの分野で FPGA が注目されている．

合成には Intel HLS Compiler[4] が用いられ，この高位合

このような背景の下，理化学研究所計算科学研究セン成系もそのような仕組みを提供している．一般的な，単体

ターでは，HPC の新たな計算アーキテクチャとして FPGAの FPGA を用いるシステムの動作シミュレーションは十クラスタシステム ESSPER を開発している [3]．ESSPER分にサポートされており，この手法で問題なく動作のテストが行える．

12a)
b)
c)
d)
e)
f)
g)

長崎大学
〒 852–8521 長崎県長崎市文教町 1–14
理化学研究所計算科学研究センター〒 650–0047 兵庫県神戸市中央区港島南町 7–1–26
fukuda@pca.cis.nagasaki-u.ac.jp
ikehara@pca.cis.nagasaki-u.ac.jp
kmoto@pca.cis.nagasaki-u.ac.jp
tmanabe@nagasaki-u.ac.jp
yuichiro@nagasaki-u.ac.jp
tomohiro.ueno@riken.jp
kentaro.sano@riken.jp

c 1959 Information Processing Society of Japan⃝

しかし，複数の FPGA で構成されたシステムのシミュレーションは，Intel HLS Compiler では十分にサポートされておらず，高位合成の恩恵を完全には受けられないのが現状である．複数の FPGA からなるシステム全体のシミュレーションを C++記述ベースで行うことはできず，関数などの細かい単位でテストを行うなどの妥協が必要である．
上記の問題を克服するため，本研究では複数の FPGA が1

情報処理学会研究報告
IPSJ SIG Technical Report

協調して動作するようなシステムの動作シミュレーション手法について検討した．また，その手法を実現するフレームワークの実装を行った．

2. 関連研究1 とコード 2 を統合した例である．
各変換で考慮すべき点と，出力されるソースコードとの対応について述べる．特に明記しない限り行数はコード 3内の行番号を指す．

1 について，コンポーネントの関数では ihc::launch お

吉内らは，大規模システムの分割実装の際に利用できるよび ihc::collect のみを呼び出すという規約にする．こ分散 RTL シミュレーションを提案した [5]．大規模システの状況では変数名の衝突は起こり得ないため，そのまま内ムを複数の FPGA に分割実装するような構成のシミュレー容を結合すればよい．ただし，ihc::collect はタスクのションは単一のマシン上で行われるが，これにはパフォー終了までブロックするため，ihc::collect の呼び出しはマンスの問題を伴う．吉内らの研究では複数の FPGA を全ての ihc::launch の呼び出しの後に配置しなければな用いるシステムのシミュレーションを分散環境で行うためらない．この変換の結果，17–25 行目の部分が出力される．のシミュレーションモジュールとデバイスドライバを実装

2 については，もともと別の関数であり同名の引数を持し，従来手法でのシミュレーションより 2.33 倍から 5.70つ可能性があるため名前が衝突しうるという点がある．そ倍の高速化を達成している．

こで，全ての引数にモジュール名でプレフィックスをつけ新井らは，C++で記述した複数のコンポーネントの統ることにする．それに伴って，関数内で当該引数を使用し合シミュレーションのための通信フレームワークを提案している箇所は参照先の修正が必要である．この変換の結た [6]．各コンポーネントは C++で記述された単体テスト

果，19–20 行目が書き換えられる．

で行えるものの，複数のコンポーネントを組み合わせた場

3 についても，分割してコンパイルすることを前提とし合の統合テストは RTL で行う必要があった．新井らの手ていたソースコードであるため，2 と同様に単純に結合する

法では C++で実装された publish/subscribe 通信フレームと名前の衝突が問題となる．そのため，衝突する変数名をワークを利用し，C++記述のまま機能シミュレーションを変更するなどの対策が必要である．C++には namespace

行える．

機能により，単一の実行環境に複数の名前空間を定義する

弘中らは，M-KUBOS というマルチ FPGA クラスタのことが可能である．そのため，引数と異なりモジュールごHLS 向けのメッセージパッシングインタフェース (MPI)とに異なる namespace に定義を移動することにより名前を提案した [7]．これは，FPGA 間通信を行うアプリケーの衝突を回避する．この変換の結果，5–15 行目が出力さションを標準的な MPI アプリケーションとして実装できれる．

るものである．シミュレーションも可能であり，ローカル

4 については，ihc::stream 型の接続用の FIFO バッ

マシン上ではソケットを使用した通信を行うマルチプロセ

ファを新たに宣言して接続する．ストリーム出力インタ

スアプリケーションとして FPGA 間通信が再現される．

フェースである ihc::stream_out への write とストリー

3. シミュレーションフレームワーク
3.1 提案手法

ム入力インタフェースである ihc::stream_in からの readを，接続用の FIFO バッファへの read/write に変換することで実現可能である．ただし，接続箇所を機械的に判定すIntel HLS Compiler を使用する場合，単一のテストベンることは不可能なため，コード 4 のような設定ファイルかチから複数のコンポーネントを並列実行することはできなら与えることを想定している．この変換の結果，3 行目にいものの，単一のコンポーネントから複数のタスクを並列新たに変数が宣言され，7 行目と 13 行目の参照先が書き換実行することは可能である．そのため，コンポーネントにえられている．

含まれる全てのタスクの実行を 1 つのコンポーネントにま別の考慮すべき点として，ヘッダファイルを名前空間内とめることにより複数コンポーネントで分散して行われてでインクルードすべきでないという点がある．include ディ

いた処理を単一コンポーネント内で完結させることが可能

レクティブは関数や変数の宣言が記述されたソースコードである．また，コンポーネント間で通信を行う場合にも，を展開しているにすぎないため，本来の名前空間と異なるタスク間の通信に変換することで同等の処理が可能である．

名前空間でライブラリ関数を宣言したことになってしまい，この際にソースコードに必要となる変換は次の 4 つでリンク時にエラーとなるためである．そこで，include ディある．

レクティブはモジュールごとの namespace の外で include( 1 ) component 属性が適用された関数の内容を結合するすることにする．この場合モジュール内で定義した変数を( 2 ) component 属性が適用された関数の引数を結合する

外から参照できるようヘッダファイルに宣言を記述してい( 3 ) グローバルに宣言された関数や変数を統合するた場合には正常に動作しないことになる．この点について( 4 ) モジュール間の通信をタスク間の通信に変換する
コード 3 はこれらの変換を適用することによってコード

c 1959 Information Processing Society of Japan⃝は現時点ではヘッダファイルの使用は Intel HLS のライブ
ラリとモジュール共通の宣言が主であると判断し，特に対2

情報処理学会研究報告
IPSJ SIG Technical Report

策は行わないこととした．
コード 1: module a.cpp
1#include "HLS/hls.h"231524component hls_avalon_slave_component
void module_a_module_b(
hls_avalon_slave_register_argument ihc::
mm_master<float> &module_a_mm_in,
hls_avalon_slave_register_argument ihc::
mm_master<float> &module_b_mm_out) {ihc::launch<::module_a::read_sender>(&module_a_mm_in);
ihc::launch<::module_b::receive_writer>(&module_b_mm_out);
ihc::collect<::module_a::read_sender>();
ihc::collect<::module_b::receive_writer>()

25

}

17
18

ihc::stream_out<float> st_out;

19void read_sender(ihc::mm_master<float> *mm_in)

20{
st_out.write((*mm_in)[0]);672213component hls_avalon_slave_component
void module_a(
hls_avalon_slave_register_argument ihc::
mm_master<float> &mm_in) {ihc::launch<read_sender>(&mm_in);
ihc::collect<read_sender>();14}

9101112#include "HLS/hls.h"2323;

コード 4: 設定ファイル
コード 2: module b.cpp

121}

8}

1645}

1412
3
4

ihc::stream_in<float> st_in;

45
6void receive_writer(ihc::mm_master<float> *mm_out) {(*mm_out)[0] = st_in.read();6

modules:- "hw_mod/module_a.cpp"- "hw_mod/module_b.cpp"
connections:- from: "module_a.st_out"
to: "module_b.st_in"

57}

3.2 変換の自動化
ソースコードの変換を自動で行うコード変換系を C++8で実装し，orochi というコマンドラインユーティリティとして使用できるようにした．このプログラムにはプロジェ

13component hls_avalon_slave_component
void module_b(hls_avalon_slave_register_argument ihc::
mm_master<float> &mm_out) {ihc::launch<receive_writer>(&mm_out);
ihc::collect<receive_writer>();14}

ファイルを全て読み込み，抽象構文木の構築を行う．C++9101112

クト立ち上げ時用に雛形コードを出力する機能なども実装しているが，ここではコード変換処理についてのみ述べる．
コード変換の主な処理の流れは以下のようになる．
まず，設定ファイルから与えられたモジュールのソースのパーサは GCC[8] や Clang[9] といった C++コンパイラ

コード 3: 結合済みのモジュール
1#include "HLS/hls.h"
ihc::stream<float> conn_port_0;

4

namespace module_a {6void read_sender(ihc::mm_master<float> *mm_in) {7::conn_port_0.write((*mm_in)[0]);5}89近い形態で出力を行いたいため，今回の要件には合わないと判断したため，独自のパーサを実装した．C++の仕様は23が実装しているものの，コードの変換後に元のテキストに}10

namespace module_b {void receive_writer(ihc::mm_master<float> *12mm_out) {13(*mm_out)[0] = ::conn_port_0.read();11c 1959 Information Processing Society of Japan⃝

膨大であることから，高位合成での使用頻度が低い構文は現時点では未実装である．
次に，構築した抽象構文木を走査し，参照しているヘッダファイルのうち，システムにインストールされているもの以外を検索し，出力ディレクトリにコピーする．この操作が必要な理由は，出力ファイルにインクルードディレクティブがそのままコピーされるため，元のハードウェアモジュール用のディレクトリに存在していたヘッダファイルにアクセスできなくなるためである．
その後，構築した抽象構文木を走査し，与えられたモジュールを結合した新たなモジュールのソースコードを生3

情報処理学会研究報告
IPSJ SIG Technical Report

成する．
最後に，出力ディレクトリに生成されたソースコードを書き出す．
なお，トークンや抽象構文木のオブジェクトは明示的に変換の処理の流れは以下のような流れで行う．

( 1 ) インクルードディレクティブの抽出( 2 ) 接続に使用する変数の抽出( 3 ) 変数の参照の書き換え

指示されない限りコピーが行われないように実装してい( 4 ) component の生成る．これによりオブジェクトのコピーによる性能劣化を防( 5 ) モジュール間通信用の変数の生成止したりメモリを節約したりする効果が見込まれる．

( 6 ) モジュール別 namespace の生成

3.2.1 字句解析

( 7 ) 生成したコード片のマージ

Flex を用いて生成した字句解析器を使用している．

「インクルードディレクティブの抽出」ステップでは，全入力ファイルをトークンに分割する．後述する構文解析

ソースファイルからのインクルードディレクティブの抽出器はここで生成されたトークンを Token クラスのインスタを行う．これは通常インクルードディレクティブは names-ンスとして受け取るようにしている．

pace 内で行うべきでないため，後のステップで namespace

コード生成後に入力と近い形態で出力したいため，トークンの文字列と空白文字やコメントを保持する必要がある．

内にインクルードディレクティブが配置されてしまわないようにするためである．

ただ，空白文字を単一のトークンとして処理してしまうと，「接続に使用する変数の抽出」ステップでは，設定ファイ後の構文解析で使用する文法規則に空白文字トークンを含ルで定義された，モジュール間の接続に関係する変数の抽めなければならなくなり，冗長になる．そこで，トークン出を行う．これにより，不必要となる変数宣言を除去するとトークンの間にある空白文字もトークンにデータとしてとともに通信に使用するデータの型情報を取得している．

保持するようにした．
具体的な字句解析の流れは以下のようになる．字句解析器が空白文字列を読み取ったとき，その文字列を一時的な「変数の参照の書き換え」では，接続に使用する変数の抽出のステップで抽出された変数への参照を，後に生成するモジュール間通信用の変数への参照に書き換える．

変数に保存しておく．コメントを読み取った際にも空白文「component のマージ」ステップでは，全モジュールか字と同様の扱いをする．字句解析器が通常のトークンを読ら component 属性が適用された関数を抽出し，1 つのコンみ取ったとき，トークンの文字列と共にその時点で保持さポーネントにマージする．全ての ihc::launch の呼び出れている空白の文字列をトークンオブジェクトに保存す

しは ihc::collect の前の配置しなければならないため，る．ファイルの終端のスペースの保持はトークンではなく呼び出しの並べ替えも行う．

ファイルが保持するものとして，構文解析のステップで処「モジュール間通信用の変数の生成」ステップでは，理している．

元の通信用変数の型情報を利用してモジュール間通信

3.2.2 構文解析用の変数を新たに生成する．この際，元の接続用の変Bison を用いて，C++記述された構文解析器を生成し使数は ihc::stream_in<type>か ihc::stream_out<type>

用している．このステップでは構文解析を行い，抽象構文の 型 で あ る が ，こ れ ら は read と write の い ず れ か 一

木を構築する．

方のみが可能である．これを read/write 操作が可能な

ソースファイル内の式や文といった要素は Partial としihc::stream<type>に書き換えることにより，接続元タスて抽象化し，具体的な構文上の要素はここから派生したサ

クで書き込んだデータを接続先タスクで読み出せるようにブクラスで保持することにした．Partial クラス自体は要なる．

素のタイプ，ファイルへの書き込み，再帰的な走査などの「モジュール別 namespace の生成」ステップでは，変共通する操作を行えるインタフェースを定義している．

数名や関数名の衝突を避けるため，モジュールごとに別

3.2.3 コード生成の namespace に宣言を移動する．orochi ではさらに，モ構文解析によって構築された抽象構文木を走査し，モジュールを結合した新たなソースコードを生成する．
変換の際，モジュール間の接続の情報が必要であるが，その情報はコード 4 のような YAML 形式 [10] の設定ファイルから取得する．YAML ファイルの解析には yaml-cpp[11]を利用した．
ここでも Token や Partial のオブジェクトのコピーを避ジュールごとの namespace を，新たに生成した namespaceの内部に配置している．これはグローバルな空間には他のライブラリの宣言が存在する可能性があり，それらとの名前の衝突を避けるためである．
「生成したコード片のマージ」ステップでは，これまでのステップで生成したコードをコンパイル可能な形に統合し，ファイルに書き出している．

けて実装している．オブジェクトを元のオブジェクト集合から取得し，元のオブジェクト集合から削除する操作をこ
こでは抽出と呼ぶことにする．

c 1959 Information Processing Society of Japan⃝

3.3 既存のツールチェーンとの親和性
実際のプロジェクトでは make のような差分ビルド可能

4

情報処理学会研究報告
IPSJ SIG Technical Reportなツールを使用している．差分ビルドではファイルのタイ場合と比較した作業効率の差はさらに大きくなると考えら

ムスタンプを確認し，ソースファイルが生成物よりも古いれる．

場合はコンパイルをスキップするという実装がなされている．シミュレーション用実行ファイルのコンパイルには時

4.2 性能評価間がかかるため，本システムが差分ビルドを妨げると，ビ4.2.1 方法

ルドに必要な時間が長くなり，ソースコードの変換の自動2 つの単純なモジュール使用し，モジュールの結合を行っ化による恩恵が少なくなってしまう．そこで，ソースコーた後にシミュレーションの実行ファイルをビルドし，全体ドの変換にも差分ビルドの機能を実装した．orochi の差分の所要時間に占める変換処理の時間の割合を計算した．そビルドは 2 つの処理からなる．それが，依存するヘッダの際に，各モジュール内部のタスク数を変化させて繰り返ファイルのうち必要なもののみをコピーし直す処理と，入し計測を行った．

力ファイルが更新されていた場合のみ変換を行う処理であ内部のタスク数が 3 の場合のモジュールの例をコード 5，る．2 番目の処理である依存するヘッダファイルのコピー

コード 6 に示す．これはコード 5 の mm_in から読み取っには，使用しているヘッダファイルの検出が必要なため，た値が全ての関数を経由してコード 6 の mm_out に書き込

ソースファイルのパース自体を避けることはできない．

まれるモジュールである．変換処理によってコード 5 の変換処理全体の流れを説明する．まず，入力であるモst_out は，コード 6 の st_in に接続される．

ジュールのソースファイルを全て読み，抽象構文木を構
コード 5: 評価に使用するコードの例（1）

築する．次に，抽象構文木の中からインクルードディレク
ティブを探し，以下の全てを満たすもののみを出力ディレ

1

クトリにコピーする．

2( 1 ) ソースファイルの存在するディレクトリから探索して，ヘッダファイルが見つかる

3
4#include "HLS/hls.h"
ihc::stream_out<float> st_out;
ihc::stream<float> pipe0;

5( 2 ) 見つかったファイルは出力先のファイルより新しい

6

最後に，入力ファイルに出力ファイルよりも新しいものが7void func0(ihc::mm_master<float> *mm_in) {pipe0.write((*mm_in)[0]);含まれていた場合のみ，ソースコードの変換処理を行う．

8}

94. 評価
コード 5 とコード 6 を例に，コードの自動変換により11void func1() {st_out.write(pipe0.read());

12}

10

設計者が手動で記述すべきコードの量がどの程度削減で13きるのかを評価する．さらに，大規模な実装で本研究で実14装したコード変換系を使用することを想定し，コードの15変換のパフォーマンスについても評価する．なお，これら

16のコードは，1 つの ﬂoat 型のデータをコード 5 の func0,func1，コード 6 の func0, func1 をこの順で経由し，mod0の mm_in から mod1 の mm_out に転送するものである．

4.1 実装するコード量

20component hls_avalon_slave_component
void mod0(
hls_avalon_slave_register_argument ihc::
mm_master<float> &mm_in) {ihc::launch<func0>(&mm_in);
ihc::launch<func1>();
ihc::collect<func0>();
ihc::collect<func1>();

21}

171819

コード 5 とコード 6 からコード 7 のようなコードが生成される．統合後のコードを用いたシミュレーションにおい

コード 6: 評価に使用するコードの例（2）て入力した値と同じ値を読み出せることが確認できた．この 46 行のコードを生成するためには，設計者は 6 行程度1の設定ファイルを記述すればよいため，ハードウェアのモ3ジュールのソースコードを設計者自らコピーして同等の変4換を手動で行う場合と比較して，設計者の負担を大きく削5減できる．

6

実際の科学計算向けのシステムを実装する場合にはさらにコードベースが拡大し，複雑な変更が必要になると考えられるため，設計者がハードウェア用のモジュールのコードを変更してシミュレーション用のモジュールを作成する

c 1959 Information Processing Society of Japan⃝#include "HLS/hls.h"2

ihc::stream_in<float> st_in;
ihc::stream<float> pipe0;

7

void func0() {pipe0.write(st_in.read());

8}

9void func1(ihc::mm_master<float> *mm_out) {11(*mm_out)[0] = pipe0.read();105

情報処理学会研究報告
IPSJ SIG Technical Report12}

1320component hls_avalon_slave_component
void mod1(
hls_avalon_slave_register_argument ihc::
mm_master<float> &mm_out) {ihc::launch<func0>();
ihc::launch<func1>(&mm_out);
ihc::collect<func0>();
ihc::collect<func1>();

21}

1415
16171819

コード 7: モジュールの統合の結果生成されるコード例#include "HLS/hls.h"
2 #include "HLS/hls.h"
3 #include "orochi.h"1456mod0_mm_in);
ihc::launch<orochify::mod0::func1>();
ihc::launch<orochify::mod1::func0>();
ihc::launch<orochify::mod1::func1>(&mod1_mm_out);
ihc::collect<orochify::mod0::func0>();
ihc::collect<orochify::mod0::func1>();
ihc::collect<orochify::mod1::func0>();
ihc::collect<orochify::mod1::func1>();39

namespace orochify {
ihc::stream<float> conn_port_0;

40414243444546}

モジュール内部のタスク数を N 個にしたとき，FIFO
バッファおよび他モジュールとの通信用のポート，タスクを処理する関数，ihc::launch の呼び出し，ihc::collectの呼び出しが N 個ずつ生成される．よって，タスク数を 1増加させたとき，空行を除くソースコードの行数（SourceLines Of Code: SLOC）は 6 増加する．
変換およびシミュレーションのコンパイルは Intel Xeon

7E3-1225 プロセッサ (3.30 GHz)，メモリ 16 GB のマシンでnamespace mod0 {9 ihc::stream<float> pipe0;

8 回実行し，その平均実行時間を評価した．

810void func0(ihc::mm_master<float> *mm_in) {12pipe0.write((*mm_in)[0]);11134.2.2 評価結果と考察
タスク数を増加させてシミュレーションを行った場合にも，入力した値と同じ出力値を得られた．よって，本手法は規模の大きいモジュールのシミュレーションにも適用可}

14能であることが確認できた．モジュールあたりのタスク数

void func1() {
16::orochify::conn_port_0.write(pipe0.read()ごとの変換時間と，統合処理前後のコンパイル時間のグラ15);
1718}}モジュールをそれぞれコンパイルし，その合計時間を参考としてプロットしたものである．統合を行わずに実際にシミュレーションが行えるというわけではない．また，統合

19

namespace mod1 {21 ihc::stream<float> pipe0;2022

後の全体の処理時間（変換とコンパイルにかかった時間の合計）に占める変換時間のグラフを図 2 に示す．
変換処理前後のコンパイル時間を比較すると，タスク数

void func0() {24pipe0.write(::orochify::conn_port_0.read()23);
25

フを図 1 に示す．統合処理前のコンパイル時間は，2 つの}が 4000 を超えたあたりから統合後のモジュールのコンパイルのパフォーマンスが低下している．これは，コンパイ
ラが巨大なモジュールのコンパイル時にパフォーマンス低26下する実装になっているか，メモリの使用量が増加したこ

void func1(ihc::mm_master<float> *mm_out) {28(*mm_out)[0] = pipe0.read();とによってスワップアウトが発生している可能性があると272930}}3132}

35363738

図 2 から，モジュールの規模が大きくなった場合にも全体の処理時間に占める変換時間の割合は 0.3% 程度に収まっている．処理時間への相対的な影響は小さいことから，設計時に使用する際の体感的なコンパイル時間への影響は3334考えている．

component hls_avalon_slave_component
void orochi(hls_avalon_slave_register_argument ihc::
mm_master<float> &mod0_mm_in,
hls_avalon_slave_register_argument ihc::
mm_master<float> &mod1_mm_out) {ihc::launch<orochify::mod0::func0>(&c 1959 Information Processing Society of Japan⃝

軽微であると考えられる．また，全体の処理時間に占める変換時間の割合は，4000 を超えたあたりから減少している．このことから，変換処理はコンパイルで発生するようなパフォーマンスの低下の影響を受けておらず，モジュールの規模が大きくなるほど全体の処理時間に対する相対的な変換処理時間の影響は小さくなると考えられる．ただ，

6

情報処理学会研究報告
IPSJ SIG Technical Report

モジュールの規模がさらに拡大すると，変換処理でも同様の結果生成された大きなモジュールはコンパイルにかかのパフォーマンスの低下が発生する可能性はある．

る時間が長くなったため，この原因の調査が必要である．
また，実際のモジュールと比較して単純なモジュールを使5用しているため，実際のコードベースの特性を反映していコンパイル時間（統合後）コンパイル時間（統合前）

1600

ない可能性がある．この点については，今後実際のアプリ

1400

4

ケーションのソースコードを用いた評価を行う必要がある．コードの変換がシミュレーションの性能に与える影響

31000
800

2600

変換時間 [s]コンパイル時間 [s]

1200

変換時間

4001

についての検証も必要である．
参考文献
[1]

200
001000

2000

3000

4000

5000

06000

モジュールあたりのタスク数

[2]
[3]

図 1: 変換とコンパイルの所要時間[4]0.6

変換処理時間/処理時間 [%]

0.5

[5]

0.4

0.3

[6]

0.2

0.1

001000

2000

3000

4000

5000

6000

[7]

モジュールあたりのタスク数

図 2: 処理時間全体に占める変換処理時間の割合[8]

5. おわりに
本稿では，C++で記述された複数 FPGA 向けのハード[9]ウェアの動作シミュレーション手法の提案と，それを実現するためのコード変換系の実装と評価を行った．
これを利用することにより設計者は数行の設定ファイルの記述から，複数モジュールを統合したシミュレーション用のモジュールを生成することができ，シミュレーション

[10]
[11]

Mack, C. A.: Fifty Years of Moore’s Law, IEEE Transactions on semiconductor manufacturing, Vol. 24, No. 2(2011).
Bohr, M.: A 30 Year Retrospective on Dennard’s MOSFET Scaling Paper, Technical report, IEEE (2007).
佐野健太郎，上野知洋，宮島敬明，Jens Huthmann，小柴 篤史： ESSPER: 高性能計算のためのスケーラブルかつ柔軟な FPGA クラスタシステムの開発，電子情報通信学会技術研究報告. RECONF, リコンフィギャラブルシス
テム， Vol. 120, No. 339, pp. 7–12 (2021).
Intel Corporation:
High-Level Synthesis Compiler- Intel® HLS Compiler, https://www.intel.com/content/www/us/en/software/programmable/quartus-prime/hls-compiler.html.
( 参 照 日:2023/01/11).
吉内大成，中條拓伯： スケーラブル・ハードウェア機構
による分割回路のための分散 RTL シミュレーション，組込みシステムシンポジウム 2015 論文集， Vol. 2015, pp.
137–138 (2015).
新井健太， 大川猛，大津金光，横田隆史： 高位合成可能なC++記述のための分散ミドルウェアを用いた機能シミュ
レーション，研究報告組込みシステム (EMB)， Vol. 2019,No. 6, pp. 1–2 (2019).
弘中和衛，飯塚健介，天野英晴： M-KUBOS マルチ FPGAにおける HLS 向けメッセージパッシングインタフェースの実装，電子情報通信学会技術研究報告. RECONF, リコ
ンフィギャラブルシステム， Vol. 122, No. 286, pp. 61–66(2022).
Free Software Foundation: GCC, the GNU Compiler
Collection - GNU Project, https://gcc.gnu.org/. (参照日: 2023/01/18).
LLVM Project: Clang C Language Family Frontend for LLVM, https://clang.llvm.org/. (参 照 日:2023/01/18).
The YAML Project: The Oﬃcial YAML Web Site,
https://yaml.org/. (参照日: 2023/01/18).
Jesse Beder: GitHub - jbeder/yaml-cpp: A YAML parser
and emitter in C++, https://github.com/jbeder/
yaml-cpp. (参照日: 2023/01/18).

における設計者の手間を大幅に削減できる．今回の実装では C++の文法を全て網羅したものではないため，実際のアプリケーションの実装に使用するには対応する文法の拡充が必要になると考えられる．ESSPER では FPGA 間をより複雑なトポロジで接続することができるため，この点についても別途検討が必要である．
変換の処理にかかる時間について，実行ファイルのコンパイルを含む全体の処理時間の 0.3% 未満となり，処理時間への相対的な影響は十分に小さいといえる．ただ，統合

c 1959 Information Processing Society of Japan⃝

7