Previous ToC Next

32. GRAPE の開発---前史 (2006/11/4)

GRAPE (GRAvity PipE) は、私達が 1988 年頃から開発を続けてきている一連 の重力多体問題専用計算機です。どういうもので、なんのためにやっているか、 ということを、私の個人的な視点からまとめます。ここは事実を客観的に書く べきところですが、当事者である以上そんなのは無理なので書く本人の意志と しては客観的であろうとしていますが読む人はそんなことはないかもと思って 読んで下さい、というものです。

私が重力多体問題というものにかかわるようになったのは大学院の修士課程に 進学した時です。少し昔話になりますが、私の進学した大学院は当時の名前は 東京大学大学院総合文化研究科広域科学専攻というところで、この名前からは 全く何をするところかわかりません。ついでにいうと学部は東京大学教養学部基 礎科学科第二というところです。これも名前だけでは意味不明ですね。この学 科や大学院がどういうところであったかという話は長くなるのでしませんが、 この学科は卒研が2つありました。1つは11月頃までにやるもので、普通に研究 室に配属されてやる研究、もうひとつはそれが終わってから3月まで、研究室 に属するのではなく4年生でグループを作ってやるもの、となっていました。 後者のものについてはここではいいことにして、前者のほうでは私は気候モデ ル、特に二酸化炭素の温室効果を数値シミュレーションする、というのをやっ てました。指導教官がそういうことの専門家であったわけでも必ずしもなく、 手探りで始めた研究で、実際にやったことは当時既に古典であった真鍋先生の 1960 年代の仕事の再現、という感じのものです。

そういう研究を続けていればもうちょっと人類の役に立つことができていたか もしれませんが、修士に進学する時にテーマと指導教官を変えることにしまし た。これは色々理由があったのですが、その1つはきっちり答がでる問題をし たかったこと、もうひとつは、その、なんというか、指導教官と研究テーマと 自分の相性みたいなものです。変えた先が杉本大一郎で、私が選んだ修士の研 究のテーマは重力多体系の進化、というものです。研究対象はある意味では非 常に単純なもので、同じ質量の沢山の星からできた星団みたいなものが、十分 時間がたった時にどういうふうになるか、というものです。

これは、星と分子を置き換えると、普通の気体とはどういうものか、という、 熱力学や統計力学の基礎と同じ話です。但し、違うところは2つあって、一つ は星同士の相互作用は重力だけなのに対して、普通の気体はまあ大雑把にいって分 子とかは大きさをもった粒子で物理的にぶつかってはねかえるものであること です。この結果、星同士はぶつかってはねかえることで熱平衡になる、という わけではなく、もうちょっとややこしい、お互いの重力で軌道を変えるような 効果で熱平衡に向かう進化をすることになります。

もうひとつは、これも相互作用が重力であることによるのですが、断熱壁や等 温壁で囲まれた密度一様なものを考えるわけではなくて、自分自身の重力でま とまっているものを考える必要があるということです。

この話と計算機との関係は、こういった系の研究ではなるべく沢山の粒子を使 いたい、ということと、でも粒子の数を少し増やすと計算量がどーんと増える ので計算は急速に大変になる、ということです。

例えば、箱の中の気体分子、というものだと、 1000個も分子がある計算をす れば熱平衡の性質を大雑把に見るには十分な場合もあります。これは、結局、 みたい性質が熱平衡状態で、これは、定義としてどの分子をみても十分長い時 間みれば同じだし、またどの場所をみても同じ、というものだからです。

重力多体系ではそう簡単ではないところがあります。この辺は少し難しい話に なりますが、大雑把にでも説明しないと何故そもそも速い計算機が欲しいか、 というのがわからないと思いますので少しお付き合い下さい。

断熱壁でできた箱の中に気体が入っている、という設定は普通の熱力学と同じ ですが、箱がものすごく大きくて気体の重力が効くような場合、言い換えると 太陽のような星1つを断熱壁で囲んだものを考えてみます。もちろん、星一つ を囲むような断熱壁というのは SF の中でしかありえませんが、まあ、そうい うものも考えるのが理論的な科学研究です。

四角い箱だと計算が面倒なので、球形の箱だとすると中のガスも球対称に分布 し、重力があるので中心のほうが密度、圧力が高い状態になります。この状態 で、全体を冷やしていくことを考えてみます。つまり、なんらかの方法でエネ ルギーを抜くわけです。そうすると、もちろん温度は下がります。また、圧力 は減ります。この結果、重力の効果は大きくなるので、中心によりガスが集まっ て中心のほうは密度が上がり、外側は下がります。つまり、横軸にエネルギー、 縦軸に中心密度を書いてやると、エネルギーが下がるほど密度はあがるわけで す。

ところが、エネルギーをどんどん抜いていくと、あるところでそのエネルギー に対応する熱平衡状態がなくなります。これは、物理的にありえないような気 もするかもしれませんが、そうではありません。このことは、極限的な場合を 計算してみるとすぐにわかります。極限的な場合の一つは、中心密度が無限大 になる場合です。温度一定で中心密度が無限大の場合、密度や圧力が中心から の距離の2乗に反比例することになります。この場合も、重力エネルギーは有 限の値を持ち、温度も有限です。従って、エネルギーをどんどん抜いていった 極限は、密度無限大の極限とは違うものなのです。

では、密度無限大の極限にいく時に、系のエネルギーはどう振る舞うか、です が、これは、振動しながら極限の値に行く、ということが数値計算するとわか ります。これは、解析的にわかることではなく、密度構造を数値的に求める必 要がありますが、まあ、ここではそうなっていると思って下さい。 振動するということは、エネルギーはどこかで最小値がある、ということです。 このため、そこを越えてエネルギーを抜くと熱平衡状態がなくなります。

熱平衡がなくなる、とはどういうことか、というと、元々温度勾配がないとこ ろで勝手に熱が流れだし、その結果温度差がもっと大きくなる、ということで す。これは普通の物質とは逆で、普通は温度勾配があると温度が高いほうから 低いほうに熱が流れ、その結果温度が高いところは温度が下がり、低いところ は上がって、温度勾配がなくなっていくわけです。これは、普通は比熱が正で あることに対応しています。

つまり、熱平衡がない、ということは、比熱が負になっているところがある、 ということに対応しています。 もちろん、ガス自体は仮定した性質を持つわ けで圧力一定とか密度一定なら比熱は正です。しかし、重力を考えると話はそ んなに簡単ではなくなります。中心の重力が強い領域を考えると、そのへんか ら熱を抜くと圧力が下がって全体としては収縮するのですが、その結果重力が 強くなってかえって温度があがる、ということが起きてしまうからです。

そうなると、ますます温度差が大きくなって、中心は収縮しながら温度がどん どんあがる、ということがおきます。これは、普通の星でも星団でも同じで、 実際にそのようなことが起こります。が、ひとつ違うことがあります。それは、 星では密度があがると熱が流れにくくなることです。この時には、中心部といっ てもある程度大きな領域がそのまま全体として縮んでいきます。また、縮む速 度は段々遅くなります。これに対して、星団だと密度があがると熱が流れやす くなり、この時には縮む領域が小さくなり、質量も小さくなるのと、その速度 がどんどん大きくなり、ある時刻で密度や温度が無限大になります。

さらに、星の場合には、密度が十分あがると核融合反応が始まって、流れ出す 熱を補って定常状態にある太陽のような普通の星ができることになります。 元々の理想化した問題で断熱壁があるとその分全体として温度が上がってしま いますが、実際の星では光の形で外にエネルギーを捨てているわけです。

では、星団ではどうか、ということになります。実際の星団だと星の大きさと かがありますが、理想化した質点の場合を考えてみます。星団の中心部の密度 がどんどんあがると、核融合と同じようなことがおきます。2つの星が連星に なるのです。これは、たまたま3つの星が近づいた時に、その2つが連星になっ て、その分の重力エネルギーをもう一つの星の運動エネルギーと自分自身の重 心運動のエネルギーに変換する、ということです。さらに、一度連星ができる と、それが他の星と相互作用したら連星の軌道半径が縮まって、その分の運動 エネルギーがまた他の星の運動エネルギーに変換されることもあります。

核融合との違いは、例えば水素原子がヘリウム原子核になった時にでるエネル ギーは決まっているのですが、重力では(ニュートン力学の範囲では)無制限に エネルギーを取り出すことができることです。これは、量子力学でなないので 基底状態がない、ということによっています。また、重力は距離の 2 乗でし か落ちないという意味で遠距離力であり、核力と違って遠くまで影響するので、 連星ができたあとの進化を計算する時に連星の内部の星の軌道運動と周りの星 の運動との相互作用も結構常時計算しないといけなかったりします。

と、だらだら要領を得ない話をしてきましたが、いいたかったことは何かとい うと、要するに重力多体系の研究では、理想化された単純な問題の場合でも 本当に多体問題を数値的に解くことが研究の重要な道具になる、ということで す。

何が起こるか、ということが基本的にはわかっている場合には、現象の本質を 取り出してモデル化、ということができますし、それが科学研究の基本的なや り方であることはいうまでもありません。しかし、「ニュートン重力で相互作 用する質点の系では何が起こるか」という、問題設定としては極めて単純で ニュートン自身だって問題にできたようなことで、実際に 10 年ほど前に大規 模な数値計算ができるようになるまではわかっていなかったことがあったので す。

私が大学院生になった時は、指導教官であった杉本が、星団の進化について新 しい発見をした直後でした。杉本は、星団の進化を実際に星の運動を解くこと で計算するのではなく、星の内部のような流体力学的な近似をする方法で研究 していました。当時は、連星ができることで中心の収縮が止まる、というのが わかってきた頃で、では連星ができたあとの星団の構造や進化はどうなるのか、 ということが問題でした。一つの星では、主系列段階といっても中心で水素の 核融合反応が始まって、あまり大きさとか明るさが変わらない状態が長い間続 きます。これに対応する状態はあるのか?ということです。

このような問題に早い時期にアプローチしたのはミシェル・エノンです。エノ ンはニース天文台の天文学者ですが、天文学の研究よりもカオス的な力学系の 研究の先駆者としてのほうが有名かもしれません。エノン・ハイレス系と言わ れる単純な平面内の運動で、エネルギーの値によっては運動が強くカオス的に なることを見いだしました。

星団の進化の研究に対しての貢献はカオス力学への貢献ほど有名ではないかも しれないですが、重要さでは決して劣るものではありません。1960年代初頭に エノンはモンテカルロ法と呼ばれている星団進化の計算方法を確立しました。 これは、多体問題をそのまま時間積分するのではなく、それぞれの星の軌道の 進化を一旦確率微分方程式の形に直し、その方程式をモンテカルロシミュレー ションすることで星団の進化を計算する、という方法です。これによって、そ れまでは全くわかっていなかった星団の熱力学的進化というものが計算できる ようになったのです。モンテカルロ法はプリンストン大学やコーネル大学の研 究者にも使われるようになりました。

それはともかく、 1970年代に入るとエノンはモンテカルロ計算に上の連星に よるエネルギー生産の項も取り入れたシミュレーションを始めます。その結果 は、基本的には星団全体が膨張する、というものでした。主系列段階の星と基 本的には同じなのですが、エネルギーが光子の形で逃げていってしまうことは ないので、生産されたエネルギーの分だけ星団全体のエネルギーが増えて膨張 するのです。膨張すると進化のタイムスケールが遅くなるので、結局無限に時 間がたっても無限に大きくなるだけで星団は存在できることになり、理論的な 問題としての星団の最終状態はどういうものか、には一つの答がでた、と当時 は考えられたと思います。その後、違った手法でも同じような結果がでました。 直接の $N$ 体計算では、扱えた粒子の数が 200 個とかその程度で、一つの連 星のエネルギーが星団全体のエネルギーと同じ程度、という状況だったので、 結果をどう解釈すればよいかわからない、という感じだったように想像します。

しかし、 1982 年になって、杉本と当時の共同研究者であったベトウィーザー は奇妙なことに気が付きます。彼らも、基本的にはエノンと同じように連星の エネルギー生産をいれた計算を、しかしモンテカルロ法ではなく流体近似でやっ ていました。彼らの計算では、中心部の密度が、5-6桁にもおよぶ非常に振幅 の大きな振動をするのです。連星のエネルギー生産は非常に密度が高くなった 瞬間にだけ起きていて、密度が低くなる(膨張する)時には中心部に外側から熱 が流れこむ、すなわち中心のほうが外側より温度が低くなっていて熱が流れこ み、その結果膨張して一層温度が下がる、ということが起きていました。

これはしかし、他の人の計算結果とは全く違っていたので、本当に彼らの計算 や解釈は正しいのか、というのが大論争になります。私が大学院に進学する前 の年、 1984 年にプリンストン高等研究所で開かれた国際研究会、 IAU シン ポジウム No. 113 では中心的な話題になったようです。この時点では、振動 解を出していたのは杉本とベトウィーザーのグループだけ、振動しないで全体 が膨張する解は、エジンバラ大学のダグラス・ヘギー、プリンストン大学のジェ レミー・グッドマン、同じくプリンストン大学のハルダン・コーンといった、 複数のグループが別々の方法で得ていました。どう考えても振動解のほうが旗 色が悪いところです。

しかし、この研究会での彼らの議論から、予想外なことがわかります。 ヘギーの計算結果とベトウィーザーの計算結果を比較していた時に、杉本が、 ヘギーの計算では時間積分のタイムステップを長くとりすぎていて、振動を 抑えこんでしまっている、と指摘したのです。ヘギーによると、杉本は、彼の 計算コードの出力をしばらく眺めたあと、 "Your timestep seems a bit large" といったそうです。では、というのでタイムステップを短くして再計 算したら、ヘギーの計算コードでも振動が起きました。

何故このようなことが起きたかというと、数値計算の標準的な方法では、タイ ムステップは、「その間に密度があまり変化しない程度」にとるからです。こ の方法では、不安定現象があっても、その成長より長いタイムステップでは不 安定現象を抑えこんでしまうことがあります。後から考えてみると、このよう な熱力学的な不安定現象を数値計算で出すためには、中心部の熱力学的なタイ ムスケール、つまり温度勾配があったとして熱が流れるタイムスケールより十 分に短いタイムステップをとる必要があるのは当然なのですが、長いステップ で計算して答がでてしまったのでそんなことには気が付かなかったのです。

こう書いてしまうと、杉本とベトウィーザー以外の研究者が単に間抜けであっ ただけでは、という印象を持つ読者もいるかもしれませんが、これは決してそ うではないです。科学の発展というのがそもそもこういうもので、後からみた らこんなことは当たり前、ということがなかなかわからないものだからです。

杉本はこの振動に「重力熱力学的振動」という名前をつけていたのですが、こ の研究会をきっかけにこの言葉は世界に受け入れられていくことになりました。

さて、そういうわけで、流体近似した計算では振動が起こる、というのは1986 年頃までには広く認められるようになったのですが、では実際に星からできた 星団でそんなことが起こるのか?というのが次の課題になりました。結局のと ころ、それを確認する、もっとも確実な方法は実際に近似が入らない多体系の 数値計算をする、というものです。ベトウィーザーと杉本は、1983 年にはそ のような計算を始めていたのですが、粒子数が少なかったこともあってなんだ かよくわからない、というのが周りの研究者の評価でした。

さらに、上にもでてきたグッドマンが、流体近似の範囲内ですが厳密な解析を 行って、振動が起こるかどうかは粒子数で決まる、ということを見つけだしま した。大体粒子数が 8,000 くらいのところに境界があり、それより下では振 動はおきない、というのです。このため、多体計算をするとすれば、それくら いまでやらないと本当のところはわからない、というのが予測されていたわけ です。

多体計算の計算方法は基本的には力任せで、1つの粒子の加速度を計算するの に他の全粒子からの力を計算します。もっとも、粒子毎に時間刻みを独立に変 えることで、中心部で密度が上がってタイムステップが短くなっても外側のほ うは長いタイムステップであまり計算量が増えないような方法を使っていまし た。これはケンブリッジ大学で学位をとったアーセス博士のアイディアによる もので、彼はそのあと 40年以上にわたって多体計算のプログラム開発をリー ドしてきました。

熱力学的な進化のタイムスケールは、粒子数が増えるとほぼそれに比例して長 くなります。このため、計算量は粒子数のほぼ 3 乗に比例して増加すること になります。私が大学院修士1年生だった時、最初は国立天文台の三鷹キャン パスのメインフレームで最大 400体、その秋には野辺山宇宙電波観測所のもう 少し性能が高いメインフレームを数十時間使って 1000体の計算をしました。 さらに、12月から1月にかけて、東大の大型計算機センターのスーパーコンピュー ター、日立の S-810 を使うことになり、プログラムのベクトル化などの作業 をしたあと 10時間程度の計算時間でやはり 1000粒子の計算をしました。

これらの計算を色々解析することで、振動の原因となる不安定性は働いている かもしれない、という兆候は見えたものの、決定的な結果とはいいがたいもの でした。この後しばらく、私も実際にもっと粒子数が大きい計算をする、とい うことよりむしろ、将来そういう計算ができるようになるための原理的な問題 の解明や、新しい計算法の開発をやっていました。

この直接のきっかけは、1986年、私が修士2年の夏にまたプリンストンで開か れた研究会にいってきたことです。数年前にプリンストン高等研究所の教授に なったばかりのピート・ハット、これは 84 年の研究会の主催者でもあったの ですが、が、星団や銀河の研究に大規模なスーパーコンピューターを使う可能 性について議論しよう、ということで 1986年夏に研究会を組織しました。こ の直接のきっかけの一つは、 NSF (アメリカの国立科学財団、日本では文部科 学省がやっている科学研究費の配分のうち、軍事等に関係しない基礎科学の部 分を担う)がアメリカ国内 5 箇所にスーパーコンピューターセンターを作り、 その1つがプリンストンに出来たことです。サンディエゴ、イリノイ、ピッツ バーグ、コーネル、プリンストンの5大学にでき、当初はコーネルが IBM のメ インフレームに付加ベクトルプロセッサをつけたもの、プリンストンが ETA システムズの ETA-10 (但し、センター設立には間に合わずその前身の CDC Cyber-205 が納入された)の他は Cray の機械が入りました。

プリンストン高等研究所はフォン・ノイマンの本拠地であり、彼が ENIAC, EDVAC にかかわったあと自力で開発を始めた IAS コンピュータが設置された アメリカの計算機科学、計算科学の起源ともいうべき場所なのですが、 1986 年当時は計算機といえば DEC VAX-11/780 があるだけでこれはとても強力な計 算機といえる代物ではありませんでした。当時の国立天文台の計算機に比べて も 1/10 以下の能力です。しかし、突然 NSF のスーパーコンピューターセン ターが近くに建設されることになり、そのような大規模計算によってどんな新 しいことができるか、というのを議論しよう、ということでピートは研究会を 組織し、杉本も招待しました。しかし、杉本は当時大変忙しかったのかなんか 知らないですが、とにかく私に代わりにいく?といってきて、私がいって東大 の計算センターの日立 S-810 でのベクトル化の話をすることになりました。

ちょうどその前後に、アーセスが日本にきて、2人で東大センターで彼のコー ドのベクトル化のテストもやっていたので、多分その時点では私はアーセスの プログラムのベクトル化について世界でももっとも経験があった、ということ になります。まあ、こう書くとすごそうですが、要するに世界中でそんなこと に手をだしたのが2-3人しかいないようなあんまり研究者の多くない分野だっ た、ということでもあります。そういうわけで、1986 年6月にプリンストンに いってその話をしました。ピートは私の話を聞いて何に感心したのか、もう2 週間ほど余計に滞在して計算量評価について論文を書こうといってくれて、そ の時、それからその夏に彼が京都に来た時、次の年の夏と色々議論したりテス ト計算をしたりして、こういった計算コードの計算量が粒子数にどういう依存 するかの結構きちんとした理論モデルを構築しました。そういうのは当時は、 というか今でもそうなのですが、あまり「研究」とは一般的にはみなされてな くて、これを論文にして専門誌に載せるのは色々大変だったのですが、その後 の GRAPE の開発等にはこの理論的な評価が非常に重要でした。

年があけて 1987 年春には杉本がプリンストンにいきました。その時に、彼は ピートから「これからは並列計算だ、特に Connection Machine が有望」とい う話を聞いてきます。Connection Machine (以下 CM)というのは、MIT の AI Lab で学位をとった W. D. ヒリスが博士論文で提案したマシンで、当時の VLSI 技術を使って単純な 1 ビットプロセッサですが最大 65,536 台(1チップ に 16 プロセッサなのでチップ数では 4096)を1台の SIMD 計算機に構成した ものです。最初は AI 用ということで並列 LISP とかの実装が考えられた、とい うより、元々並列 LISP である CM-LISP の概念が先にあって、それを実現す るハードウェアとして CM を考えたものです。ピートは 1985 年に当時プリン ストン高等研究所のポスドクだった J. バーンズと有名なツリーコードを発明 したのですが、これを CM 上に載せるというのを 86 年の夏から秋にかけてやっ ていました。その話を杉本は聞いたわけです。

CM は元々は上に述べた通り 1 ビットのプロセッサを大量につけたもので、あ まり数値計算向けではありませんでした。クロックサイクルが 5MHz 程度で、 浮動小数点演算には数千サイクルかかったので、1プロセッサは 1kflops 程度、 マシン全体でも 100Mflops 程度の性能しかなかったからです。しかし、 R. ファインマンの助言などがあり、浮動小数点演算専用 LSI を搭載した CM-2 が生まれます。これはプロセッサチップ2つにつき1セット、最大 2048 セットでしたが、 1 セットが 10 Mflops 程度の演算能力を持っていたので 最大構成(といっても 1辺が 2m もない立方体ですが)では 20Gflops と、1986 年時点ではベクトル機を上回り事実上世界最高速の計算機でした。

なんだか自分の話が多くてすみませんが、 1986 年の夏に私はツリーコード の話を聞いたので、これは面白いと思ってその秋から冬にかけて自分で書いて みたりしていました。これは、今はなき Borland の TurboPASCAL とかで書い たものです。そうこうしているうちに夏になり、 Piet から論文仕上げるとか 色々するからプリンストンにこい、と言われて2ヶ月ほどいきました。この時 にはツリーコードのアルゴリズムををベクトル機で実行できるように書き直す、 ということにも手をだしました。これは、1986年には Los Alamos にいた Hernquist が Barnes が書いたツリーコードを Cray XMP 用の CIVIC Fortran コンパイラ(Los Alamos で開発しもの)で動くようにしたものを、プリンスト ンの CDC Cyber 205 上の FTN200 Fortran コンパイラで動いて性能がでるよ うにしよう、という話です。

CIVIC は良くできたコンパイラで、Fortran のくせに再帰が使えたりポインタ があったりしたようです。が、ベクトル化機能は大したことはなく、当時の日 本メーカーのベクトル化コンパイラのほうがはるかに優れていました。 問題は、 Hernquist のベクトル化法ではスカラ実行に比べて性能が2倍程度に しかならなくて、あまりよろしくない、ということと、上の事情で再帰を使っ ていたので FTN 200 では動かない、ということでした。再帰については、バー ンズ自身が明示的にスタック操作をすることで再帰をループに変換したプログ ラムを書いてとりあえず動くようにしたのですが、性能がでないのはそのまま でした。

ツリーコードは、N体系をツリー構造で表し、ツリーを辿っていくことで1つの 粒子への力を計算します。ツリーを辿るアルゴリズムの自然な表現は再帰的ア ルゴリズムなのですが、別に自然でなくても計算機で実行できて速ければいい ので色々な方法が実は可能です。

再帰的アルゴリズムには、 Fortran ではそもそも実行できない、ということ の他、ベクトル化もできないという問題がありました。再帰的アルゴリズムに は実は自然な並列性があるのですが、関数呼び出しのない DO ループしかベク トル化しないベクトル化コンパイラではそんなものは扱えません。

結局、この時には私、バーンズ、ハーンキストの3人がそれぞれ違う方法での ベクトル化を考えついて実装しました。まあ、その、最初に成功したのは私だっ たということはちょっと主張しておきたいところです。この時は Cyber 205 でなるべく性能を上げようということであまりコンパイラに頼らずに、チュー ニングが必要なところではベクトル命令のアセンブラを直接呼ぶようにしまし た。が、これでは Cyber でしか使えなくなるので、日本の機械でも使えるよ うに、それ用に普通のベクトル化コンパイラ向け Fortran で書いたものも同 様なチューニングをしました。

この時のベクトル化の原理は、要するに違う粒子への力は並列に計算できる、 ということからベクトル化するループを力を受ける全粒子に対して回るものに する、ということです。普通に書くと、外側のループで全粒子を順番に見て、 内側のループでは現在見ている粒子への力を再帰を反復に書き換えたもので計 算します。

しかし、ベクトル化は普通もっとも内側のループにしかしてくれないので、こ のままではベクトル化できないわけです。ベクトル化するには内側のループと 外側のループの順番を入れ替える必要があります。 元々全粒子への力は並列 に計算できるのだから、そういう入れ替えはちゃんと必要な一時変数(スタッ ク)を粒子の数だけ用意すればできます。もっとも、実際にはツリーを辿るの にスタックは必要なくて、現在どこにいるかから、下の階層に行くのでなけれ ばどこの行くべきかは一意的に決まります。従って、その行くべき場所へのポ インタがあれば良いわけです。このようにすると、プログラムが簡単になって、 しかも余計な仕事が減るので速度も上がりました。

以下に当時書いた Cyber 205 用のコードを示します。

 C***
          do 40 i = 1, 3
            maxnod2=maxnode
            dxs(1,i;npnnul) = poscp(1,i;npnnul)
     &         - q8vgathr(pos(1,i;maxnod2), pnodes(1;npnnul); npnnul)
 40       continue
          stols(1;npnnul) = q8vgathr(sizetol2(1;maxnod2),
     &                               pnodes(1;npnnul); stols(1;npnnul))
          masss(1;npnnul) = q8vgathr(mass(1;maxnod2),
     &                               pnodes(1;npnnul); masss(1;npnnul))
          nexts(1;npnnul) = q8vgathr(nxtpos(1;maxnod2),
     $                               pnodes(1;npnnul);nexts(1;npnnul))
          childs(1;npnnul) = q8vgathr(fstchd(1;maxnod2),
     $                               pnodes(1;npnnul);childs(1;npnnul))
          rsqs(1;npnnul) = dxs(1,1;npnnul)**2 + dxs(1,2;npnnul)**2
     $                   + dxs(1,3;npnnul)**2
          bstom(1;npnnul) = (rsqs(1;npnnul) .ge. stols(1;npnnul))
          where (bstom(1;npnnul))
            npnods(1;npnnul)=nexts(1;npnnul)
          otherwise
            npnods(1;npnnul)=childs(1;npnnul)
          endwhere
          where ((.not. bstom(1;npnnul)) .or.
     &             (ptclcp(1;npnnul) .eq. pnodes(1;npnnul)))
     &      masss(1;npnnul) = 0.0
          rsqs(1;npnnul) = 1.0/(rsqs(1;npnnul) + eps2)
          phims(1;npnnul) = masss(1;npnnul) *
     &        vsqrt(rsqs(1;npnnul); npnnul)
          phicp(1;npnnul) = phicp(1;npnnul) -  phims(1;npnnul)
          phims(1;npnnul) = phims(1;npnnul) * rsqs(1;npnnul)
          do 90 i = 1, 3
            acccp(1,i;npnnul) = acccp(1,i;npnnul) -
     $           dxs(1,i;npnnul) * phims(1;npnnul)
 90       continue
          bnewcp(1;npnnul)= (npnods(1;npnnul) .ne. null)
          j=q8scnt(bnewcp(1;npnnul))
          if(j .lt. npnnul) then
            nend=npnnul-j
            endlst(1;nend)=q8vcmprs(pindex(1;npnnul),
     $           .not. bnewcp(1;npnnul);endlst(1;nend))
            do 230 i=1,nend
              k=endlst(i)
              pbody=ptclcp(k)
              phi(pbody)=phicp(k)
              termcnt(pbody)=termcp(k)
              acc(pbody,1)=acccp(k,1)
              acc(pbody,2)=acccp(k,2)
              acc(pbody,3)=acccp(k,3)
 230        continue
            if(j .ne. 0) then
              ptclcp(1;j)=
     $             q8vcmprs(ptclcp(1;npnnul),bnewcp(1;npnnul);j)
              phicp(1;j)=
     $             q8vcmprs(phicp(1;npnnul),bnewcp(1;npnnul);j)
              termcp(1;j)=
     $             q8vcmprs(termcp(1;npnnul),bnewcp(1;npnnul);j)
              do 240 k=1,ndim
                poscp(1,k;j)=
     $               q8vcmprs(poscp(1,k;npnnul),bnewcp(1;npnnul);j)
                acccp(1,k;j)=
     $               q8vcmprs(acccp(1,k;npnnul),bnewcp(1;npnnul);j)
 240          continue
            endif
          endif
          if(j .ne. 0) then
            pnodes(1;j)=q8vcmprs(npnods(1;npnnul),
     $           bnewcp(1;npnnul);pnodes(1;j))
          endif
          npnnul=j
こちらは、アルゴリズムの基本は同じですがあんまり邪悪なチューニングをす る前の基本的なプログラムです。ループの入れ替えをした後の最内側ループを 示しています。

 C***
          do 40 i = 1, pcount
            pbody = pfirst + i - 1
            if (pnode(i) .ne. null) then
              p=pnode(i)
              dx = pos(pbody, 1) - pos(p, 1)
              dy = pos(pbody, 2) - pos(p, 2)
              dz = pos(pbody, 3) - pos(p, 3)
              rsq = dx**2 + dy**2 + dz**2
              if (rsq .ge. sizetol2(p) .or. p .eq. pbody) then
                if(p .ne. pbody) then
                  rsq = rsq + eps2
                  r2inv = 1.0/rsq
                  rinv = sqrt(r2inv)
                  phim = mass(p)*rinv
                  phi(pbody) = phi(pbody) - phim
                  phim = phim * r2inv
                  acc(pbody, 1) = acc(pbody, 1) - dx*phim
                  acc(pbody, 2) = acc(pbody, 2) - dy*phim
                  acc(pbody, 3) = acc(pbody, 3) - dz*phim
                endif
                pnode(i)=nxtpos(p)
              else
                nodediv = nodediv + 1
                pnode(i)=fstchd(p)
              endif
            endif
 40       continue
Cyber 用のコードは3倍くらいの長さになった上、なんだか意味がわからない ものである、というのはわかるかと思います。これはコンパイラの能力の問題、 ということもできなくもないのですが、下のプログラムから上のプログラムに 対応するようなアセンブラ、というか上のプログラムは q8xxxx というのはそ のままベクトル命令に変換されるのでほぼアセンブラなのですが、を出すこと をコンパラに期待するのはなかなか現実的ではない、というかコンパイラを書 く人にそんなことをやってというのには無理があるかもしれません。

まあ、とにかく、そういうわけでツリーコードのベクトル化も結構上手くでき ました。そこで、 CM でもやってみよう、という話になって、 87年の秋から 冬にかけて 3ヶ月ほどボストンの MIT AI Lab の近くにある TMC で机をもらっ てました。

TMC は、数値計算機のための計算機に何をもたせるべきか、というのは全然考 えずに人工知能屋さんがハードウェアとソフトを作っていた会社でした。 86 年にもバーンズが CM 上にツリーコードの実装をしたのですが、その時に使え た言語は *Lisp という、 Lisp に CM 上のアセンブラ呼び出し機能をつけた だけのものでした。

但し、元々 Hillis は人工知能屋で、言語設計には G. L. Steele 等の人が入っ ていたこともあり、アセンブラといっても上の FTN200 なんかに比べると全く 次元が違うものでした。CM のハードウェア、ソフトウェアの画期的な点は、 仮想プロセッサの概念を導入したことです。それまでの SIMD 並列機や、ある いはベクトル機をアセンブラでプログラムする場合もそうですが、ハードウェ アの並列性、つまり何個プロセッサがあるか、というのがプログラマに見えま す。このため、例えば 8192 粒子のシミュレーションをするプログラムを書く 時、使えるプロセッサが 256個だったとすると、 1 プロセッサが32個の粒子 を分担することになって、そのための配列宣言とかループ構造をももったプロ グラムを書くとかそういうことをする必要が起きます。 これに対して、 CMは 1つの物理プロセッサが複数の仮想プロセッサの実行をエミュレーションする、 というのを SIMD の実行レベルで行う、という仕掛けがありました。このため、 上の例では、アセンブラで書く時でも 8192 個のプロセッサを使うことができ ます。これはプログラムの生産性を非常に上げるものです。

なんだか話がそれていきますが、とにかくこの時は CM 上の C* という、C++ のクラスの機能を使って C にSIMD 並列実行機能をつけた言語でツリーコード とかを書いてました。これは、上の仮想プロセッサのおかげでかなり複雑な処 理が比較的簡単なプログラムで実現でき、まあまあの性能がでました。 ここでまあまあというのは理論ピークの10パーセントとかそれくらいです。ベ クトル機でもそんな程度なので、価格性能比の高い CM では十分競争力があり ました。

但し、これは性能評価くらいにおわって、あんまり実際のシミュレーションに は使いませんでした。シミュレーションには、プリンストンにはいった ETA-10 とか、当時リクルートがもっていたスーパーコンピューター研究所の Cray XMP や NEC SX-1 を使っていました。このスーパーコンピューター研究 所はなかなか不思議なところで、とても採算がとれるあてはなかったのではと 思うのですが、 Cray XMP、NEC SX-1、 富士通 VP-400 等の大型スパコンの他、 研究所に Alliant FX-8、 Ardent Titan、PAX-64J、Intel iPSC/2 等の並列機 がありました。大型スパコンは計算サービス部門のものですが、結構研究所の 関係者には使わせてくれました。当時東大の大型計算機センターのスーパーコ ンピューターを使うと1時間 1 万円ほどしたので、これは極めてありがたいも のでした。

と、そんなことをしていた 1988年の秋、指導教官の杉本から4ページほどの研 究会集録原稿のコピーみたいなものを渡されました。当時野辺山宇宙電波観測 所にいた近田の、「計算機を使う、計算機の技術を使う」という原稿です。 近田がその年の天文・天体物理若手夏の学校という、大学院生が中心となっ て組織する勉強会みたいなものに講演者として招待されて話をしたものをまと めたものです。

野辺山宇宙電波観測所は世界で初めて 5 素子のミリ波干渉計を動かしたとこ ろです。干渉計というのは、複数の電波望遠鏡からの信号を計算機の上で合成 することで口径の大きな電波望遠鏡と同じ分解能を実現しようとするものです。 そのための計算機の能力は望遠鏡の台数が多いほど、また観測する波長が短い ほど高いものが必要になり、野辺山の場合は 100Gflops ほどが必要でした。 ベクトル機の能力が 1 Gflops なかった時代の話です。

まともに計算機を買ったのではとても無理なのですが、近田たちは信号処 理用の専用計算機を作ることでこの処理速度を実現しました。出来たものは FX という名前で、基本的には望遠鏡からの信号を FFT (高速フーリエ変換) する専用回路です。データのビット長を FFT の部分は 6 ビット程度とするこ とでハードウェアの規模を小さくし、さらに完全専用回路とすることで 100Gops (浮動小数点ではないので fl をつけない)の速度を普通のメインフレー ム程度の規模の回路で実現しました。

近田の原稿の主旨は、そのようなやり方をシミュレーションでも使えばよ い、というものでした。見出しだけを引用すると

「昨日、今日、明日」

「性能は値段に大体比例する」

「実はオーバーヘッドの多少によって性能/価格は3桁違う」

「効率の良い implement しやすいアルゴリズムを選ぶことが大事」

となっていて、基本的な思想はこれだけでわかるかと思います。但し、杉本に とって大事だったのは、近田が単に例として「こんなハードウェアができます」 とブロック図を書いたものが粒子間の重力を計算する専用回路で、まさに私達 が必要としていたものだったことです。杉本は早速近田と接触し、PAX の慶応 の川合、その時大学院合格が決まっていた伊藤、私の3人と一緒に野辺山に出 かけて近田の話を聞きました。

その時にどういう話をしたか、というのは私は実は殆ど憶えていないのですが、 基本的には伊藤が修士の間に設計する、いろいろわからないことは近田に聞く、 というような話をしたはずです。近田の原稿を引用すると

   具体的イメージをつかんでもらうために、例として図2にパソコンにつない
   でN 体問題の重力を計算する回路の概念を示します。 10MHz クロックで間
   口がパラレルのパイプライン式で32bit固定小数点で計算させるとすると、
   市販の IC で 200個、0.1 立方米くらいの嵩で、250MOPS のスーパーコン
   ピューター並みの性能が得られるでしょう。値段としては自作で 400万円
   位でしょう。もし億円オーダーの金をかけて、大型計算機につなぐような
   バンとしたものを作る場合は、高性能を狙って専用 IC を作り、 IC 5000
   個、 4 byte 浮動小数点演算、 20MHz クロック、20立方米、 100Gflops、
   10万体問題を4万ステップ 1 日に計算できる。
とあります。
Previous ToC Next