Tag Archives: Linux

Amazon EC2 GPUインスタンス(Fermi)で金融の計算

先日(といってもかなり昔)にセットアップしたAmazonEC2のGPUインスタンスでFermiの実験してみた。(正確には下調べ。)
比較条件は以下の通り。お題は金融の世界でよく使われるブラックショールズモデルでのオプションプライシング。

  • 計測対象のオプション明細は512万件。パラメータは乱数により発生させる。
  • プレミアム、デルタ、ガンマを算出。
  • 計測はすべてdouble型。標準正規分布の累積分布関数についてもdouble型の精度のある近似式を用いる。
  • Amazon EC2のクラスタ GPU クアドラプル エクストララージを使用。GPUはFermi M2050を1つ使用。CPUは33.5ECUをフルで使用。(全力ならGPUは2つ使える。が、今回はGPU間の分散はやっていない。)
  • GPUのコンパイルなどはCUDA 3.2、CPUの方はGCC(4.1)+openMP。

結果は以下の通り。

  • CPUから見える場所に明細がある状態から計算完了(CPUから見える場所への転送完了)だとGPUが2000msecに対して、CPUは300msecくらい。(1コアのみCPUを使うと3300msecくらい)
  • GPU側に明細を転送した後からだとGPUは350msecくらいで計算を終え、計算結果をCPUから見える場所に転送できる。

ブラックショールズは計算負荷がかなり軽く、メモリ転送やデバイスの初期化に時間がかかるGPUには不利な条件。256万件だとGPU側の計算時間が「明細転送後計算開始~計算結果をCPU側にコピー完了」で230msecなので、GPUはまだ本気が出せていないよーな感じ(それを言うと、CPUも拡張命令使ってないので本気は出せていない)。
結論としてはGPU化するにはあんまり向いていない倍精度なブラックショールズ式の計算において、てきとーにコードを書いた場合でも計算部分(片道の転送時間は含む)ならば1 GPUでCPU 8コア(2つのクアッドコアNehalem)に相当する計算能力が出せるっぽい。素晴らしい。
ちなみに計算誤差は512万件分、「delta_diff += fabs( delta_cpu[i] –  delta_gpu[i]);」という感じで足しても

PREMIUM: DIFF = 0.000000026168368
DELTA: DIFF = 0.000000000065476
GAMMA: DIFF = 0.000000000001220

程度。なお、512万件の合算値はPREMIUM:52703033, DELTA:2487382, GAMMA:69438くらい。
個別でみるとほぼdoubleの限界のくらいまであっている。誤差部分はGPUの積和演算利用とか、CPUは実は微妙に拡張倍精度演算をすることがあるとか(最適化やSSEなど細かい話題次第ですが)、非正規化数の存在とかあるんだけど、どこが影響しているのかは調べていない。
むかーし試してみていたときよりもdouble型の能力・性能がかなり上がっている印象。相当向いていない処理にもかかわらずまずまずの結果だった。もうちょっと遊んでみる予定。
# NVIDIA的にはGPGPUに力を入れているようだが、新コアのKeplerが出たらAmazonも入れてくれるんだろうか?

Amazon EC2のGPUインスタンス

ひさしぶりにGPGPUがいじりたくなったが、FermiコアのVGAが無かった、かつ、追加するには電源が足りなかったのでAmazon EC2のクラスタ GPU インスタンスを使ってみた。
導入はとても簡単。(下記サイトを参考にした。)
http://stacksmashing.net/2010/11/15/cracking-in-the-cloud-amazons-new-ec2-gpu-instances/
最初にAmazon EC2でインスタンスの立ち上げ。

  1. Amazon WebServicesに申し込む。
  2. AWS ManagerからEC2を選んで、US WEST(Virginia)でLaunch Instance。
  3. インスタンスタイプは“Cluster Instances HVM CentOS 5.5 (AMI Id: ami-aa30c7c3)”
  4. 秘密鍵のダウンロード、securityの設定などを行い、インスタンスの立ち上げ。

次にSSHでインスタンスに接続し、下記コマンドで開発環境を整える。(CUDA SDKはもっと新しいバージョンが出ているので本来ならば最新版を使うべきだと思う、が、とりあえずの実験なので上記のサイトに従った。)

wget http://developer.download.nvidia.com/compute/cuda/3_2/sdk/gpucomputingsdk_3.2.12_linux.run
chmod +x gpucomputingsdk_3.2.12_linux.run
./gpucomputingsdk_3.2.12_linux.run
yum install automake autoconf gcc-c++

やっていることはSDKのダウンロードとインストール、makeやgccの導入。
次にライブラリにパスを通す。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64

これで開発環境はそろい、「~/NVIDIA_GPU_Computing_SDK/C/」のなかの適当なサンプルをコンパイルして実行できるようになる。
SDKのバージョンが2のときに作った二項モデルでのオプションプライシングのプログラムも普通に動いた。CPUでの演算と比べて15倍くらい速い。このインスタンスはCPUもかなり強力なのでまずまずの値ではないかと思う。(二項モデルはGPUのアクセラレーションが効きにくい上、試したのはFermiより前のGPUに最適化したプログラム。)
思ったより簡単・安価に開発環境が整えられた。もうしばらく遊んでみようと思う。
(料金の詳細は http://aws.amazon.com/jp/ec2/#pricing を参照。イメージとして計算インスタンスは200円/時間 程度、ストレージは10円/GB/月 程度で、計算インスタンスを止めている間はストレージの料金しかかからない。)

CD Linux(Live CD)を使ってシンクライアントもどきを作ってみた。

目指す大体の構成は

  • 古いPCのハードディスクを引っこ抜いてディスクレスにする。
  • 1CD Linuxから起動、リモートデスクトップ(rdesktop)で他のPCにつないで作業する。

というもの。
手順は大体こんな感じ。

  1. Puppy Linuxをダウンロード。
    http://openlab.ring.gr.jp/puppylinux/
    ※ CDのカスタマイズが簡単に可能というすばらしいディストリ。しかも軽い。
  2. CDに焼いて起動。
  3. パッケージマネージャからrdesktopをインストール。
    ※バージョンが古いのでWindowsVista以降にリモートログインする場合は最新版を入れる必要がある。
    http://www.murga-linux.com/puppy/viewtopic.php?t=31702
  4. 起動スクリプトやらデスクトップやらネットワークやらを適当に設定。
  5. CDのリマスタリング機能(Puppy Linuxの標準機能!)でCDを焼く。
    ※3、4で行った設定を全て焼きこむ。
    ※設定の一時保存先としてUSBメモリがあると楽。
  6. PCのハードディスクを抜き、CDドライブに5.のCDを入れる。
  7. 再起動後、rdesktopで他PCにログインして作業する。

この環境では基本的にファイルの保存はできないし、何かあっても再起動で全部消える。単純にPCを盗まれてもデータ漏洩の可能性が無いという意味ではそこそこシンクライアントだと思う。
とはいえもどきなので、Linuxのコマンドがローカル環境に大量に存在するとか、USBメモリを突っ込むなどやる気になればローカルにデータ保存が可能とかいう問題はある。「もどき」を取るためには、USBのマウントをさせない、CD-R/DVD-Rのような書き込み可能デバイスをつけない、ネットワークの接続先を限定する、余計な実行ファイルを消して変なことができない構成にするなど工夫が必要。