Erlangで初心者的なことをやって
自信を回復しようとしているみけです。
Erlangでのプロセス間通信
spawn
という関数を用いて関数を実行すると、その関数のプロセス識別子が取得出来ます。
そしてプロセス識別子に対して
!
演算子を用いることで、プロセスに対してメッセージを送信することができます。
フィボナッチ数列の計算
ところで、Erlangでフィボナッチ数列を計算する関数は簡単に書けます。
-module(fib).
-export([fib/1]).
fib(N) when N < 2 -> 1;
fib(N) ->
fib(N - 1) + fib(N - 2).
ところが、この関数はひとつのプロセスで実行するために、
値が大きくなると途端にパフォーマンスが低下します。
3> timer:tc(fib, fib, [10]).
{11,89}
4> timer:tc(fib, fib, [12]).
{24,233}
5> timer:tc(fib, fib, [14]).
{61,610}
6> timer:tc(fib, fib, [20]).
{1546,10946}
timer:tc
関数の戻り値の一つ目の要素が実行時間(ms)です。ガクガクって増えていっている様子がわかります。
そこで複数プロセスでフィボナッチ数列を計算する
そこで、
fib:fib
関数を少し修正して、プロセス間通信する形で計算してみます。
では、試してみます。
3> timer:tc(fib, fib, [10]).
{2889,89}
4> timer:tc(fib, fib, [12]).
{5109,233}
5> timer:tc(fib, fib, [14]).
{5684,610}
6> timer:tc(fib, fib, [20]).
{132777,10946}
う〜んと、値が大きい割には、値の増え方が緩いですね。
では、40くらいだとどうなるでしょうか?
7> timer:tc(fib, fib, [10]).
結果が返ってきませんねー
あ、え、エラー…
too many processes
だってwというわけで
まあ、何が問題だったかというと、
所詮4コアしか積んでいないマシンで無数のプロセスを起動すると、
死ぬ
というわけですね。
まあ、当たり前と言っちゃ当たり前ですね。
さて、では、プロセス数を4より増やさないようにして
書いてみたのが次のやつになります。
関数
fib
はひとつのプロセスでやる奴。関数
cfib
は二つのプロセスでやる奴。関数
ccfib
は四つのプロセスでやる奴。で、実際に時間を計測してみました。
だいたい、16〜20くらいで、複数プロセスの効果が現れていますね。
0 件のコメント:
コメントを投稿