Previous | ToC | Next |
今年度からポスト富岳FSも始まって、牧野もシステム調査研究に採択された2つ の提案のうち1つの代表として関わることになりました。
他の Tianhe-2A、Summit、Frontiers はCPUとアクセラレータでメモリ空間が別で、 使うのはそれなりに大変です。
従って、ここでは、我々が CPU、アクセラレータ、といっている時にそれは実際には 何をいっているのか、という概念整理を試みます。
さて、CPUベースのシステムについては、我々のイメージは明確です。システ ムとしては、Xeon、あるいは ARM、SPARC のような、その上のOSが動くマルチ タスクなCPU の対称型(これはそうでなくてもいいですが)マルチプロセッサで、 1ノードはコヒーレンシがある階層キャッシュによる物理的共有メモリである ものです。
ノード内の並列化には、プロセス並列の MPI とスレッド並列の OpenMP (OS的 には pthread)がどちらも、通常はハイブリッドの形で使えることになります。
これが「使いやすい」というのは、要するに OpenMP で並列化できるので 並列化してないプログラムの並列化をインクリメンタルにできるとか、 プラグマによるもので並列化しない動作も可能であるとかだと思います。
そうすると、システム側からみた「CPUベース」の条件は
例えば、何か並列に実行できるループを OpenMP で並列実行したとしま す、並列実行できる、ということは、そのループを実行中にあるプロセッ サが更新したデータを他のプロセッサが使うことはない、ということで す。なので、少なくともループの実行中は、キャッシュが更新された、 という情報を他に伝える必要はありません。ループが終わって、他のプ ロセッサが自分の更新したところをアクセスする可能性がでる直前に、 ライトバックして書換え情報を共有するか、そもそも書いたあとでロー カルキャッシュを全部クリアすればよいわけです。もちろん、OpenMP の ループ毎にプライベートキャッシュを全部捨てるのは必ずしも賢い方法 ではありませんが、コヒーレンシだけが解ではありません。プライベー トキャッシュを捨てる、という方法は賢くなさそうですが、コヒーレン シプロトコルと違ってコアが数増えてもトラフィックが増えない、スケー ラブルな方法であるというメリットもあります。
細かいところまでちゃんと理解していないのでここは嘘を書いているか もしれませんが、PEZY-SC では実際にコヒーレントがないキャッシュが 採用されていて、あるPEが更新したデータを他のPEがアクセスする前に 実際に2つが属するキャッシュレベルまでのフラッシュが必要で、上に書 いたのに近い仕掛けになってるのではないかと思います。なお、PEZY-SC の階層キャッシュの特徴は、L2, L3 と下にいくと非常にラインサイズが 大きくなることで、これは(近くのPEが近くのアドレスをアクセスするよ うになっていれば)アドレストラフィックを減らし、非常にバンド幅が高 い L2, L3 の実現を可能にしています。
とはいえ、ここで書いていることは要するに、 OpenMP は
逆にいうと、完全でないサポートであれば SIMD でも問題ありません。例えば、 元々ベクトルプロセッサでベクトル化されていたようなループを OpenMP (+SIMD) で並列化しています、というものは、ベクトルプロセッサ自体が SIMD プロセッサとみなせるわけでもちろん SIMD プロセッサで(主記憶が共有 されていれば)実行できます。
ループではなくて配列表記ですが、 HPF の元になったともいえるCM-Fortran はもちろん 完全 SIMD で流体とかQCDに普通に使われてたわけでそれなりに広 い範囲のアプリケーションを記述するだけの表現力もあります。 つまり、並列実行が非常に複雑な、コア毎に全然違うことをするようなもの でなければ、「OpenMPが動けばいい」というアプリケーション側の要請に 答えるのに原理的には CPU である必要は全くないことになります。
もちろん、データセンターとかで仮想マシンにインスタンスを多数動かすとか ウェブサーバーとかだと本当にCPUの並列性が必要(ただそうすると共有メモリ である必要が全くない気がしますが、、、)ですが、少なくとも我々がHPCアプ リケーションを動かす、という時に求めることは「pragma omp parallel for を並列実行してくれる」ということでしょう。深層学習だと話はもっと簡単で、 PyTorch とか JAX とか(まあこれらがHPFみたいなものですが)が動けばよい。
それなら別に parallel for を動かすところはCPU でなくても 大規模 SIMD ユニットでも GPU でもあるいはMN-Core でもいいじゃないかという気もする わけですが、それには、「起動とデータ転送オーバーヘッドが十分小さいなら」 という条件があります。例えばカーネル起動に数十マイクロ秒もかかっていては、 ものすごくがんばってカーネルの数を減らしても性能をだすことは 難しいですし、また、ホストメモリとデバイスメモリの間のデータ転送や その起動にさらに時間がかかっていては話になりません。
これは、
まあその、1 には、どういうコアを使うか問題がもちろんあり、 64 bit ARM コアは高いとか、そういう問題はあります。とはいえ最近だと RISC-V が かなり使えるようになってきています。
そうすると、なんとなく形がみえてくるかな、というところです。
Previous | ToC | Next |