Think Parallelで行こう!

第2回 現代のプロセッサと並列実行

株式会社フィックスターズ
中村 孝史

2009/8/24

Single Instruction Multiple Data

 スーパースカラーでは、実行ユニットの並列化にあわせて命令デコーダも並列化する必要がありました。実行を高速化したいだけなのに、命令デコーダも並列化する必要があるのは少し無駄なように思われます。なんとかならないのでしょうか。

 デコーダを並列化しなければならない理由は、複数の処理を実行するには複数の命令が必要だからです。それならば、一命令で複数の処理をしてしまえば命令デコーダを並列化する必要がなくなるのではないか、という気がします。

 この一命令で複数の処理をしてしまうというのを実現したハードウェアがSIMD(Single Instruction Multiple Data)です。SIMDは実行ユニットだけを並列化したものです。このブロック図を図3に示します。

図3 SIMDプロセッサのブロック図
SIMDプロセッサのブロック図

 SIMDを実装したハードウェアでは、SIMD命令と呼ばれる「1つの命令で複数のデータを処理する命令」が用意されています。例えば、x86のSIMD実装であるSSEの加算命令addpsを使うと、4個の単精度浮動小数値に対して加算を行うことができます。

 この処理のイメージ図を図4に示します。画像処理などでは複数のデータに対して同じ処理を行うことが多いため、SIMDを使えば効率良く処理することができます。

図4 SSEのaddps処理
SSEのaddps処理

 ただし、SIMDは明示的にSIMD命令を使わなければ活用することはできません。この命令を使うようにソフトウェアを書き換える必要があります。標準のC言語では、これらの命令を使う方法がないので、SIMD命令を使うようにソフトウェアを書き換える場合は、コンパイラの拡張機能を使うか、もしくはアセンブリプログラムを直接書く必要があります。

 x86のSIMD命令であるSSEを使うプログラム例をリスト3に示します。配列に含まれる32ビット単精度浮動小数値の加算をしています。

●リスト3 SIMDを使った配列の加算
001: #include <emmintrin.h>
002: void add_array(__m128 *out, __m128 *x, __m128 *y, int n) {
003:     for (int i=0; i<n; i++) {
004:         out[i] = _mm_add_ps(x[i], y[i]);
005:     }
006: }
001行目:
SSEを使うために必要なコンパイラ拡張ヘッダです
002行目:
__m128はSSEで使うデータ型を示す型です
004行目:
_mm_add_psは4つの浮動小数値の加算を行う関数です。コンパイラによってSIMD命令addpsに変換されます

 実際のSIMDプログラミングについては次回以降詳しく解説する予定ですので、しばらくお待ちください。

マルチコア・マルチプロセッサ

 SIMDやスーパースカラーは、1つのタスクの中の処理を並列化するもので、まったく違うタスクを並列実行するのには向いていません。例えば、1000回のループを行う処理と3回のループを行う処理を同時に実行するのはかなり困難です(不可能ではないですが)。

 ループ回数の違う処理を並列に実行するには、それぞれのタスクが独立してループ処理を行う必要があります。また、複数のタスクをそれぞれ独立したOSのプロセスとして実行する場合は、各タスクはOSによって保護される必要があります。

 例えば、動画の再生とウィルススキャンを並列に実行する場合に、動画プレイヤーのバグがウィルススキャンの動作に障害を起こすようなことがあってはいけません。

 つまり、複数の処理を実行する場合、それぞれのタスクごとに独立したループ制御やメモリ保護が必要な場合があるのです。

 そこで、ループ制御やメモリ保護なども含めて、1つのプロセッサと同じ機能を持つものを並列化したものがマルチコア、マルチプロセッサになります。

 マルチコアは、architectural state、命令デコーダ、実行ユニットを並列化したものです。

図4 マルチコアのブロック図
マルチコアのブロック図

 マルチプロセッサは、architectural state、命令デコーダ、実行ユニット、キャッシュ、メモリコントローラ、バスを並列化したものです。

図5 マルチプロセッサのブロック図
マルチプロセッサのブロック図

 ただし、これらの分類はきちんとした定義に基づくものではありません。例えば、マルチコアでもキャッシュを並列化する場合もありますし、マルチプロセッサでもバスやメモリコントローラが並列化されないことがあります。

 AMDのPhoenomが出たころ、対抗のCore2Quadと比較して「ネイティブクアッド」「真のクアッド」であるなどと宣伝されましたが、これはプロセッサメーカーによって、マルチコアの定義が違うことから出た言葉であるといえます。

 ソフトウェアから見た場合にはマルチコアとマルチプロセッサは同じように見えますが、並列化されているハードウェアが違うために、性能に少し違いがあります。

 NUMAマルチプロセッサと呼ばれるマルチプロセッサ環境では、メインメモリとの通信部分が並列化されているため、シングルプロセッサと比べてメインメモリとの通信性能は向上します。

 しかし、キャッシュを別々に持っているため、プロセッサ間の通信を行う場合は、Inter Connect Busと呼ばれるプロセッサ間を接続するバスを通してデータ通信を行う必要があります。

 マルチコアの性能はこの逆で、メインメモリとの通信は並列化されておらずコア数が増えてもメインメモリとの通信性能は上がりませんが、共有データをキャッシュ内に置いておくことができ、コア間の通信は、高速なキャッシュ内で行うことができます。

 このマルチコア・マルチプロセッサの性能を活用するには、ソフトウェアを書き換える必要があります。一般的には、OSがこれを実現するためのインターフェイスを用意しており、それを通してプログラムを行います。

 これがいわゆるマルチスレッドプログラミングになります。実際のマルチスレッドプログラミングについては次回以降詳しく解説する予定ですので、しばらくお待ちください。

prev
2/3
next

Index
現代のプロセッサと並列実行
  Page1
マルチプロセッサ概説
いまどきのプロセッサの構成
スーパースカラー
Page2
Single Instruction Multiple Data
マルチコア・マルチプロセッサ
  Page3
ハードウェアマルチスレッド

index Think Parallelで行こう!/font>


Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

>

Coding Edge 記事ランキング

本日 月間