見出し画像

【VLIWからマルチコアまで】MIMDの実例3選

ムンペイです。ソフトウェアを高速化する仕事を中心に、30年以上プログラミングをしています。
別の作業に夢中になってしまい、毎週日曜公開を守れませんでした。すみません。

前回の続きで、MIMDについての経験と話題を3つご紹介したいと思います。


MIMDとは

Multiple-Instruction Multiple-Dataの略で、並列実行モデルの分類の1つです。同じクロックサイクルで複数個のデータに対して違う処理をしようという手法のことです。

Single-Instruction Multiple-Data (SIMD、シムディー)については、前回書きました。1つの命令で複数のデータを、同時に(同じクロックサイクルで)処理してしまおうというものでした。

ご推察のように、SIMDが効果的に働くのは、データがたくさんあるときです。しかし、CPUにとっていつも同種のデータを大量に並列処理をする機会があるわけではありません。むしろ異なる演算をたくさんというケースの方が大半です。

ですので、データ並列ではないケースも高速化しようとすると、MIMD方式を取り入れたくなってきます。

MIMDという言葉はFlynnという方が提案されたもので、同じクロックサイクルで、複数の命令を、(必然的に)計算回路で計算しようという、非常に抽象化された用語になります。
MIMDを実現する方式には、現在いくつかメジャーなものがあります。

1. Very Long Instruction Word

VLIWとも言われます。なんかいかにもたくさん命令を実行しそうな気持ちのこもった用語ですね。

VLIWでは、指定した複数の命令を同じクロックサイクルで実行するようにコンパイル時点で予め決めておく手法です。この「予め」というのがポイントになります。

この方式を実装したCPUで最も有名なのはおそらくIntelのItaniumでしょう。3個の命令スロットに詰め込んで同じクロックサイクルで実行することができました。詰め込む命令を実行時に調整することができるという、VLIWに独自の拡張を施したEPICという方式でした。
意欲的な内容でしたが、時代と噛み合わず廃れました。私は経験はありません。

経験があるのは、Texas Instruments (TI)社の Digital Signal Processor (DSP)C6000シリーズです。

DSPというのは、その名の通りデジタル信号処理に代表されるような膨大で単純な処理を延々と行うのに適したプロセッサのことです。って、SIMDの説明と同じですね。近年はCPUにDSP的機能が移植されて違いはすくなっています。CPUはデータ処理以外も早く実行できる工夫がされた機能も値段もリッチなプロセッサ、DSPはデータ処理だけは速いがその他はコストを抑えたプロセッサ、という感じでしょうか。

閑話休題。TI C6000シリーズは、8個の命令を同じクロックサイクルで実行できるVLIW型のプロセッサです。私の経験は20年近く前ですが、今でも同じコンセプトの後継機種があり、人気があるんですね。

専用コンパイラに、C言語(部分的にC++)のソースコードを与えると、並列化レポートを生成してくれました。アセンブリの横に、並列化できたことを示す||のマークがついたものです。下記はそのイメージです。(本物のレポートではありません)

|| ADD 
|| SUB
   LOAD

上の例だと、ADDからLOADまでの3つの命令を同時に実行できるということです。
最大8個を実現できるよう、C言語のソースコード上で実行順序を変えたり、ループをアンロールしたり、データの持ち方を変えたりしました。インオーダー実行されるため、レポート通りのサイクル数がそのまま実行時間になります。1クロック削れたときは嬉しかったものです。

2. マルチコア

昨今のCPUは、複数のコア(計算回路のセット)を持っています。これも、MIMDを実現する1つの方式です。マルチコアを使うためには、マルチスレッドプログラミングをするのが一般的だと思います。

さらに、OSレベルで考えれば、マルチプロセスで、MIMDしていると考えることもできそうです。

マルチスレッドやマルチプロセスで並列処理を書くのは結構難しい部分があります。各スレッドの実行結果をいずれは統合する必要がありますが、実行タイミングを精密には制御できないため、各スレッドの実行完了待ち(同期)をします。このロスが意外と多くなることがあり、同期を減らす工夫などが大変になるのです。

3. Single-Instruction Miltiple-Thread

GPUが採用している方式です。
1つの命令列で複数のデータを処理させる点はSIMD的ですが、データごとに何個目の命令を実行しているかは違っても良いというマルチスレッド的な特徴を兼ね備えています。

命令のための記憶領域を抑えつつ、数1000個に及ぶ膨大なスレッドを制御するために良く考えられた方式ですね。

nVidiaが、CUDAとともに言い出した用語だと記憶してますが、いまやすっかり定着したようです。

CUDAは、初期の頃にそこそこ書きました。当時は同時に1つのカーネルだけでした。いまはマルチカーネルは当然として、もっともっと制約がはずれていろいろな工夫の余地が増えているようです。その分、最適化のアイデアも必要と言うことになるでしょう。

キモはいつも同じ

こうして並べてみても、キモはいつも同じです。
依存関係のないデータや命令を同時に処理する。その余地が大きくなるよう、データ構造にも工夫する。
そういうことを考えながら、画像処理ライブラリを作ったことがありましたが、その話はまたの機会に。

これにて御免!

サポートのご検討ありがとうございます。 いただいたサポートは Code & Magic の開発運営などに使わせていただきます!