AWS の FPGA インスタンス(f1インスタンス)を使ってみる

AWS の FPGA の利用可能なインスタンス(f1)を使ってみたいと思ったが、何かに使えないとやる気が出ないので、(double)sha256 の高速化を目標にした。(bitcoinのminingに使えないのかと。)

何年か前に ASIC を作るプロジェクトに2年ほど携わったことがある程度の知識しかないので、専門用語等が間違っていてもご容赦を。

一時間あたり $1.65 なので、結構なお値段だ。

GPU か FPGA かどちらを使うべきか悩んだが、GPU は基本的には、浮動小数点演算を並列に実行するには向いていそうだが、ハッシュ処理に使われているシフトやバイトの入れ替えなどは FPGA のほうが向いていそうに思える。なんといっても、線をつなぎかえるだけなのだから。

AWS イメージ・開発環境

FPGA の HDK/SDK が搭載されているイメージは、AWS market place で、FPGA Developer AMI という名前で提供されている。FPGA を使わなければ、t2.medium などでも起動できそうだ。これなら料金を抑えられる。

インスタンスを立ち上げてみると、合成ツールとシミュレータは入っているようだった。また、ハードウェア開発キット(HDK) に一通りドキュメント、サンプルが揃っている。

実装・評価

FPGA インスタンスを使うにあたって、私の疑問点は、ホストとのインタフェースをどうするのか、というのと、ホストインタフェースを組み込んだ状態でシミュレーションできるのか、という点だ。

両方とも可能で、全て cl_hello_world に書かれている。このサンプル、本当に良く考えられていると思う反面、このサンプルが無ければ何もわからなかっただろう。

ホストインタフェース

cl_hello_world だが、ホストから適当な番地に書き込んだデータを読み出すことができるようなロジックになっているようだ。また、Virtual DIP SW/LED/JTAG などの機能もある。

このサンプルを使えば、特定の番地にデータを書き込み、読み出しすることが可能そうだ。

シミュレーション

ASIC とは違って書き換えは可能なものの、FPGA イメージを作るには時間がかかる。そのため、FPGA イメージを作っては試す、などといったことはできないし、どこが間違っているかもわからないだろう。シミュレーションで論理を検証することができるようになっており、FPGA イメージを作るほどの時間も必要ない。

さて、シミュレーションの方法だが、RTL Simulation for Verilog/VHDL Custom Logic Design with AWS HDK に記載がある。なんと、C言語でテストできる。私にとっては、かなり嬉しいし、敷居が下がった。また、実環境でのCソースも同様に用意されているので、流用できそうだ。(

sha256 の RTL は Hardware implementation of the SHA-256 cryptographic hash function にあるので、cl_hello_world を適当に編集して、sha256 モジュールと接続すればよさそうだ。make C_TEST=test_hello_world で実行する。

ハッシュ化したいメッセージを適当な番地にセットし、実行開始フラグを立て、実行完了フラグが立っていたら、戻り値を適当な番地から読み出す、これができれば、FPGA で sha256 の計算をさせられそうだ。

試してみたところ、pythonで言うところの

hashlib.sha256(hashlib.sha256(1024bitのメッセージ).digest()).digest()

は、1回あたり、1.5us (666kHash/s)前後だった。sha256 は、64 回ループ+αで、二回実行しているので、桁的には、動作クロック/100程度だろうか。

シミューレーションのため、
/home/centos/src/project_data/aws-fpga/hdk/cl/examples/cl_hello_world/verif/scripts/top.vivado.f に追加したファイル(私の例ではsha256_core.vなど) を入れる必要がある。

ちなみに、ここまでで、丸々3日ほどかかってしまったが、ハードウェア設計・実装に精通していれば、もっと早いだろう。

合成

ファイルを追加したので、いくつか変更する必要があった。

/home/centos/src/project_data/aws-fpga/hdk/cl/examples/cl_hello_world/build/scripts の
* encrypt.tcl の file copy 〜 とある箇所にファイルを追加
* synth_cl_hello_world.tcl を以下のように変更(追加したファイルが verilog だったから?)

read_verilog [glob $ENC_SRC_DIR/*.v]
read_verilog -sv [glob $ENC_SRC_DIR/*.sv]

./aws_build_dcp_from_cl.sh を実行するとメモリが足りないよ、と言われるので、-ignore_memory_requirement を付けて実行。

デフォルトはバックグラウンドで(nohupコマンドで)実行されるが、-foreground を付ければ、画面に表示されるので、screen などで端末が切断されても復活(screen -r)できるようにして実行。

4〜5時間かかった。

シミュレーションでは動作しても、実機上で同じ結果にならず、試行錯誤・・・

FPGA イメージの生成

How To Create an Amazon FPGA Image (AFI) From One of The CL Examples: Step-by-Step Guide のとおりに生成する。

ポイントは
* S3 の設定で、AWS にアクセス権を与えること
* IAM の設定で、EC2 full access か何かの権限を与えること (S3 のアクセスだけでは、create image が失敗した)

かと思う。

FPGA へのロード・実行

アカウントの初期状態では、f1 インスタンスが使えないようになっているので、AWSに制限値を上げるよう申請する。

以下のリンクを参考にイメージを作ってロード。
(FPGAイメージの作り方〜ロードの方法)[https://github.com/aws/aws-fpga/tree/master/hdk/cl/examples#3-submit-the-design-checkpoint-to-aws-to-register-the-afi]

software/runtime の下に実環境上で動作させるコードがあるので、参考に。

活用方法など

ホストとのやりとりが割と簡単なので、パターンの決まったロジックを10〜100倍にしたい時に有効な場合もあろう。(ただ、一ヶ月フルに回すと、12万ほどかかる計算なのでお気をつけて。)

とりあえず、bitcoin daemon から「宿題」をもらって、nonce に相当する部分をブン回せば、当たりが出るかもしれないので試してみよう・・・(全部 C 言語で書くのは、さすがに面倒なので、FPGAを実行させて結果を読み出して表示するという簡単な機能のC言語プログラムを python から subprocess で呼び出すか。)

それにしても、bitcoin の ASIC の性能は T Hash/s とのことで、どのように実現しているのか。個数を増やしているのではなく、パイプライン的にして、ほぼ 1 hash / clock でデータが出てくるようになっているのか。それでも数百MHash / s だろうし、想像できない数を並べているのだろうか。

レポートを見てみると、2%程度しか使っていなかったので、頑張れば、50個ぐらい詰め込めるのか?

参考

最初、GUI環境も整えたりしたが、結局は不要だった。

以下のようなソフトウェアとハードウェアの関係などにも目を通しておいたほうが理解が深まるかもしれない。

Happy a nice hacking on cl_hello_world!