第2回 現代のプロセッサと並列実行
株式会社フィックスターズ
中村 孝史
2009/8/24
CPUの周波数の高速化競争が頭打ちになり、1コアにおける処理能力は限界となった。CPUの進化がマルチコア化に向かった結果、並列コンピューティングの門戸が開かれた(編集部)
マルチプロセッサ概説
プロセッサのハードウェアは、並列プログラムとは切っても切れない関係にあります。
第1回「並列処理を体感してみよう」で説明したとおり、並列プログラムが流行する背景には、直列プログラムの高速化の限界があります。この限界は、並列化を引き起こしたというだけでなく、これまでの汎用プロセッサではあまり見られないメモリアクセスの方法や、命令実行の方法を採用したプロセッサの登場を引き起こしました。
かつてプログラムの最適化というものは、命令実行に必要なクロック数や、命令数、レジスタ数を考慮したプログラムを書くという意味でした。現代ではこれらの最適化については、パイプライン実行やレジスタ数の増加、コンパイラの最適化技術の発達によって、かなりうまく抽象化されています。
しかし、メモリアクセスの方法や特殊な命令の実行をうまく抽象化する方法はまだ見つかっておらず、これらを考慮したプログラムを書くには、プログラマが問題にあわせて創意工夫をする以外の方法はありません。
つまり、並列プログラミングの時代には、プログラマが特殊なメモリアクセスや命令実行の方法などを理解したうえで、それにあわせた並列プログラムを書く必要があるのです。
ハードウェアを知らずして並列化を語るなかれ、ということで、今回は「現代のプロセッサと並列実行」と題しまして、現在の一般的なプロセッサに見られる並列ハードウェアについて解説していきます。
いまどきのプロセッサの構成
並列というと、マルチプロセッサやマルチコアのことを想像する方が多いと思いますが、実際のハードウェアを見るとほかにもさまざまなレベルで並列実行が行われている個所を発見できます。
ここではそれらを含めて現代のプロセッサに使われている並列実行の仕組みとその仕組みが採用される背景について説明します。
まずは、現代の一般的な汎用プロセッサのハードウェア構成について説明しましょう。並列ハードウェアは、いくつかあるハードウェアのうち、どの部分が並列に動作するかによって分類されており、並列ハードウェアを知るためにはプロセッサの構成というものを知っておく必要があります。
いまどきのプロセッサの構成のブロック図を示します。
各部をそれぞれ説明していきましょう。
architectural state
レジスタなどプログラムを実行するために必要なプロセッサの状態全体を含む部分です
命令デコーダ
メインメモリもしくは命令キャッシュに含まれる命令をハードウェアを実行するための信号に変換する部分です
実行ユニット
命令デコード後の信号を解釈して実際に計算を行う部分です
キャッシュ
メモリアクセスを高速化するためにメインメモリにある命令やデータを一時的に蓄えておく部分です
メモリコントローラ
メインメモリとのデータのやりとりを行う部分です
バス
メインメモリや周辺機器のデータを運ぶ部分です
メインメモリ
データを蓄えておく部分です(ここではキャッシュメモリと区別するために「メイン」メモリとしておきます)
実際のハードウェアになると、もう少し細かく区切られたり、区切りが曖昧になったりしますが、大体はこのような理解で問題ないと思います。
スーパースカラー
先ほどのブロック図で示したように構造を分けた場合、プログラムの実行を速くするには、その名前からして実行ユニットを並列化して同時に複数の命令を実行できるようにすればよい、という気がします。
これは実際にそのとおりで、どんなプログラムもよく見ると並列処理できる個所があるのです。例えば、リスト1のように何も考えずに書いたシングルスレッドのプログラムのループでもiのインクリメント、iとnの比較、そしてsum+=a[i]の部分は同時に実行できます(iの値の更新に注意する必要がありますが)。
for (i=0; i<n; i++) { sum += a[i]; }
これを同時実行できるハードウェアがあれば、プログラムを高速実行できるようになるでしょう。
スーパースカラーは、これを実現するもので、実行ユニットを並列化したものです。また、実行ユニットが複数になった場合、それにあわせて複数の命令を同時にデコードする必要があるため、命令デコーダも並列化してあります。
スーパースカラーのブロック図を示します。図中で黄色で示される部分が並列化されている個所です。
スーパースカラーは基本的にはソフトウェアからは見えないようになっていますが、スーパースカラーを意識してプログラムを書き、プログラムを高速化することは可能です。
例えば、足し算を一度に複数実行できるプロセッサの場合は、リスト2のように書くことで高速化できる場合があります。
for (i=0; i<n; i+=2) { sum0 += a[i+0]; sum1 += a[i+1]; } sum = sum0 + sum1;
リスト1のプログラムでは加算に依存があるため並列実行できませんが、リスト2のプログラムでは依存がなく加算が2並列同時実行できます。
1/3 |
Index | |
現代のプロセッサと並列実行 | |
Page1 マルチプロセッサ概説 いまどきのプロセッサの構成 スーパースカラー |
|
Page2 Single Instruction Multiple Data マルチコア・マルチプロセッサ |
|
Page3 ハードウェアマルチスレッド |
Think Parallelで行こう! |
- プログラムの実行はどのようにして行われるのか、Linuxカーネルのコードから探る (2017/7/20)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。最終回は、Linuxカーネルの中では、プログラムの起動時にはどのような処理が行われているのかを探る - エンジニアならC言語プログラムの終わりに呼び出されるexit()の中身分かってますよね? (2017/7/13)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。今回は、プログラムの終わりに呼び出されるexit()の中身を探る - VBAにおけるFileDialog操作の基本&ドライブの空き容量、ファイルのサイズやタイムスタンプの取得方法 (2017/7/10)
指定したドライブの空き容量、ファイルのタイムスタンプや属性を取得する方法、FileDialog/エクスプローラー操作の基本を紹介します - さらば残業! 面倒くさいエクセル業務を楽にする「Excel VBA」とは (2017/7/6)
日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。本稿では、業務で使うことが多い「Microsoft Excel」で使えるVBAを紹介する。※ショートカットキー、アクセスキーの解説あり
|
|