最近Elixirをちょこちょこ使ってみている。
オンラインゲームを作るプラットホームとして優れているのではないかと考えたからだ(ベースとなるerlangが電話交換機を制御するための言語なので得意なのは当たり前だが)。
また、CPU単体での性能向上に陰りが見えてきて、メニーコア環境でのプログラミングが増えて来ている。
elixir/erlangが持っているプロセスを使って、簡単にメニーコアを使えて性能が向上するなら、こちらを使って行く方が、メニーコア環境でのコア数増加の恩恵を得られるのではないかと思っている。
CPUが大量にある環境でプロセスを使うことでどの程度コアを並列に使うのか調べてみた。
調査環境
EC2のc4.8xlargeを利用して、多数のCPU環境下でelxirがどの程度CPUを使用するか調べてみた。
c4.8xlargeはCPUを36個持っている(手軽に、数ドルで、36cpu環境を試せるEC2は素晴らしいな)。
##使ったソースコード
使用したソースはこちら
簡単なKeyValueストアを作り、プロセスを作って、putをgetを行なう。
putしてその値をgetした後には何もせずに、終了する。
実行は
$iex -S mix
Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:36:36] [async-threads:10] [kernel-poll:false]
Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> PTest.test(1000)
で行なう。
実行結果
上記のコマンドを実行しつつ、topで数値を調べた。1と押すとCPU個別でどの程度使われているか出てくる。36個全部使った訳ではないが、適当にバラけて実行されているようだ。
まとめ
elixirを使えば、簡単にマルチコア環境で、並列なプログラムが書けるのではないか。
はまった所
callerの指定がわからなかった、最初
{:ok,tsk}=Task.start_link(fn -> loop() end)
send pid,{:get,key,tsk}
としなければならないところを、
{:ok,tsk}=Task.start_link(fn -> loop() end)
send pid,{:get,key,self()}
と書いていて、全くreceiveされずに、困った。
start_linkされたりspawnされたりしたら、別のself()とは別のpidが生成されるのが、ちょっとわかりづらいなと思った。