複数のMPSGEのプログラムを同時に実行する方法

シミュレーションで感応度分析を行うときには、少しずつパラメータの値を変更して何度もモデルを解くということがよくあると思います。そのようなときに単純に1個ずつ順番に解くという方法もあります。例えば、GAMSのシミュレーションで10個のパターンがあり,それを以下のようなバッチファイルで解くというような方法です.

call gams code.gms --sce=1 --tax=0.1
call gams code.gms --sce=2 --tax=0.2
call gams code.gms --sce=3 --tax=0.3
call gams code.gms --sce=4 --tax=0.4
call gams code.gms --sce=5 --tax=0.5
call gams code.gms --sce=6 --tax=0.6
call gams code.gms --sce=7 --tax=0.7
call gams code.gms --sce=8 --tax=0.8
call gams code.gms --sce=9 --tax=0.9
call gams code.gms --sce=10 --tax=1.0

最近のPCはmulti core(マルチコア)であることが多いので、ソフトウェアがmulti threadに対応してさえいれば、CPUをフルに活用することができ速く解くことができると思います。しかし、ソフトウェアがmulti threadに対応していなければ、上のように1個ずつ解くという方法では、1個のパターンを1つのコアを使って順番に解いていくだけなので、CPUはフルには活用されず効率的に解くことができません。私が利用しているGAMSは残念ながら完全にはmulti-threadに対応していないので、1個ずつ解くという方法をとっていては効率的にシミュレーションができません(数値計算の多くはmulti-thread対応のものが増えてきたと思いますが、対応していないものもあります。例えば有名な無料で利用できる統計ソフトRはまだmulti-threadに対応していないようです)。

このようなときには、自分で複数のプロセスを実行するようにするという方法があります。つまり、複数のパターンを別のプロセスとして同時に実行するという方法です。これをするには、DOSのバッチファイルから(終了を待ってから次の命令に移行する call 命令ではなく)start 命令によってGAMSを実行すればよいです。例えば、

start gams code.gms --sce=1 --tax=0.1
start gams code.gms --sce=2 --tax=0.2
start gams code.gms --sce=3 --tax=0.3
start gams code.gms --sce=4 --tax=0.4
start gams code.gms --sce=5 --tax=0.5
start gams code.gms --sce=6 --tax=0.6
start gams code.gms --sce=7 --tax=0.7
start gams code.gms --sce=8 --tax=0.8
start gams code.gms --sce=9 --tax=0.9
start gams code.gms --sce=10 --tax=1.0

というようなバッチファイルで実行するということです.

ただし、このように単純に start 命令を利用することには問題があります。というのは,これでは10個のプロセスが同時に実行されてしまうからです.

コア数が10数個あるようなPCでしたら10個のプロセスでも問題ないですが,コア数が4つしかないPCでこれを実行すると,全てのコアがGAMSによって専有されてしまい,計算中に他の作業をすることが難しくなってしまいます.計算中に他の作業も同時に行ないたいときには,「コア数−1」の数だけを同時に実行させ、残りの一つは他の作業用にとって置くという形にしないといけません.例えば、コア数が4つなら,まず初めの3つのプロセスのみ実行する.そして1つが終了したら新しくもう一つのプロセスを実行するというようになっていなければいけないです.

以上のように、自分の指定した数だけのプロセスしか実行しないようにすることは単に start 命令を使うだけでは実現できません.もっと複雑な処理が必要になるのですが,これを実現するためのプログラムが Rutherford のウェブサイトで公開されています.

http://www.mpsge.org/runjobs/

ここにあるプログラムは,元々は Jeff Price という人が作成した VB script で,それを Rutherford が少し修正したものです.特にGAMS用というわけではないので、GAMSの実行以外の用途にも使えます。

これでGAMSを実行するサンプルのコードを作成しました。これです。中に3つのフォルダがあり、それぞれに以下のようなプログラムが入っています。

  • Single: 一つずつシングルプロセスを実行
  • Approach_1: 同時に3つのプロセスを実行
  • Approach_2: 同時に3つのプロセスを実行。プロセスごとに作業フォルダを作成。

それぞれのフォルダにrun_scenarios.batというバッチファイルがありますので、実行すると各アプローチでモデルを解きます。Approach 1 と 2 は実質同じですが、2ではプロセスごとに別の作業フォルダを作成し解くという形にしています。MPSGEを利用しているときには、Approach 2のような方法でないと上手くいかないことがあります。

Approach 1 & 2は3つのプロセスを同時に走らせるので、理想的にはSingleの1/3の時間で解けるのでしょうが、私が自分のCore 2 Quad Q9650 (3GHz)というパソコンで解いてみたところ、各アプローチで

  • Single: 5分6秒(306秒)
  • Approach_1: 2分33秒(153秒)
  • Approach_2: 2分40秒(160秒)

かかりました。Approach 1 & 2は1/3とはいかないまでも半分くらいで解けます。


[2022年9月29日追記] 同じようなことを現在の家のパソコンでやってみました。これは「Intel Core i9-9900K」というCPU(8コア)を利用したパソコンです。複数プロセスのケースでは1度に10個のプロセスを同時に走らせたところ

  • Single: 2分12秒(122秒)
  • Approach_1: 49秒
  • Approach_2: 49秒

となりました。Single については 6 割減、複数プロセスについては 7 割減という時間になりました。10年も経つとやはりCPUの処理スピードがかなり改善しますね。