SML# 版 AObench をMassiveThreadsで高速化

前回*1はちょっとケチが付いてしまいましたが、今回めげずに AObenchSML の SML# 版に MassiveThreads による並列化版 を追加しました。
シングルスレッド版と並列化版を両方実行します。
並列forを実装して 並列ML: MaPLe で AObench を高速化 で作ったものと全く同じコードで動くようにしました。

パフォーマンス

私の環境で一番良かった並列化パラメータでの結果を載せます。

環境: Linux(amd64) VMWare 4core 8GB MEM

real user sys
sml#(シングルスレッド) 0m13.872s 0m9.969s 0m1.442s
sml#(4プロセス並列化版) 0m5.739s 0m19.625s 0m1.978s

2.4倍に速くなりました。ちゃんと並列化できてるようですね。

並列化の粒度調整

MaPLeと同じくSML#の場合もプロセス数と粒度をそれぞれ指定する必要がありました。
よさそうな組み合わせを探したときのログを簡単に可視化したものを以下に示します*2

AObench SML# 3.5.0 MassiveThreads 並列化版のパフォーマンスグラフ
AObench SML# 3.5.0 MassiveThreads 並列化版のパフォーマンス

x軸が MYTH_NUM_WORKERS で y軸が粒度(1スレッド内で何行計算するか)、カラーバーは実行時間(秒)です。
並列度が高くても粒度が大きすぎるとパフォーマンスが劣化していることが分かりますね。今回のケースではコアと同数のプロセス、2行(512ピクセル)分の粒度がもっとも良かったようです。

終わり

  • 今回のケースでは(エンジニア的センスで)適当に指定してもシングルスレッド版より遅くなることはあまり無さそう
  • とりあえず粒度を小さくしておいても問題無さそうなので手軽に使えそう
    • MaPLe版である程度調整済みだったので無駄な試行が少なかったのもある
  • 実験中パフォーマンスのばらつきが結構あったのはparfor内でjoinしているのが遅いのかも知れない

*1:SML#のプログラムにMassiveThreadsのオプションを付けるとパフォーマンスが低下する

*2:各頂点間の平均を取ってる色らしいので本当はあんまり良くない