Parallel Schemeに向けたテストその2

GCの並列実行が安定したので今度はGCの負荷のあるテストを行ってみました。これで性能が出るのかどうか気になる所です。テストにはcpstakを使います。このテストでは計算用スレッドと同じ数のGCスレッドが自動的に起動されています。これはスタベーションを防ぐために必要となります。

Ypsilon 0.9.6-trunk/r250 Copyright (c) 2008 Y.Fujita, LittleWing Company Limited.
> (import (time))
> (define (cpstak x y z)
    (define (tak x y z k)
      (if (not (< y x))
          (k z)
          (tak (- x 1)
               y
               z
               (lambda (v1)
                 (tak (- y 1)
                      z
                      x
                      (lambda (v2)
                        (tak (- z 1)
                             x
                             y
                             (lambda (v3)
                               (tak v1 v2 v3 k)))))))))
      (tak x y z (lambda (a) a)))

> (define n-cpstak
    (lambda (n)
      (let loop ((i n))
        (cond ((> i 1) 
               (cpstak 18 12 6)
               (loop (- i 1)))
              (else
               (cpstak 18 12 6))))))

> (time (map n-cpstak '(100 100)))
;;  1.612471 real    2.700168 user    0.012001 sys

> (time (parallel-map n-cpstak '(100 100)))
;;  0.881907 real    1.716107 user    0.016001 sys

parallel-mapによりreal時間は54.6%になりました。ここでは並列化によりuser時間も63.5%と少なくなっていることに注意してください。cpstakの総計算量は同じなのでGCの負荷が下がっているから(*1)と考えられます。

なかなか期待通りの結果なのですが、まだ解決しなければいけないことが残っています。ここは何か上手い方法(*2)を思いつきたいものです :)

(*1) GCの負荷が下がるのは世代別GCに似た効果が得られるからと思っています。
(*2) 上手い方法を思いつかないとお蔵入アイテムが増えることになるのです :o

現在のparallel-mapはまだまだ限定された条件でしか動きません。簡単にSEGVするのでtrunkでもまだサポートしていません。