はじめに
昨今マルチコアCPUは一般化し、並列化処理の重要度がどんどん高まってきました。この流れはもう変わらないでしょう。ですから、我々開発者にとって並列処理の知識は絶対に必要なものです。とはいえ、日々の業務をこなしつつ資料が少ない並列化処理を身につけることは大変です。
そこで今回筆者は、並列化処理を実現するOpenMPの入門記事を書くことにしました。OpenMPを選択した理由は、一番効率が求められているのはC/C++プログラマーだと考えたからです。C/C++プログラマーの方々が並列処理を習得するお手伝いができれば幸いです。
なお、この連載で解説に使用するサンプルコードはあくまでもOpenMPの基礎を理解するための便宜的なものであり、実務でOpenMPを使用する際にはよく理解してから用途に適したプログラミングを行ってください。
対象読者
筆者が想定している読者はCの基本的文法をマスターし、並列化プログラミングに興味を持っている方です。凝ったテクニックを極力さけ、基本的な文法さえ分かれば読めるように極力注意しますので、並列化に興味を持っている方はぜひこの連載に目を通して下さい。
必要な環境
C/C++コンパイラが必要です。お持ちでない方は無償で提供されているマイクロソフト社の「Visual Studio C++ 2008 Express Edition」をダウンロードするなどして入手してください。
次に、OpenMPを使用するために「Windows SDK for Windows Server 2008 and .NET Framework 3.5」が必要ですのでダウンロードしてインストールして下さい(※Visual Studio 2008のProfessionalバージョン以上をお持ちの方は必要ありません)。
この連載は基本的にWindows環境を想定して解説しますが、OpenMPそのものは他のOS上でも動作しますので、適宜読み替えて参考にしてください。
OpenMPの概要
OpenMPとは、複数のCPUが一つのメモリを共有するアーキテクチャでの並列性を記述するためのAPI(Application Program Interface)仕様です。このAPI仕様をサポートするベンダーが作ったコンパイラを使えば、並列的に動作するソフトウェアが作れます。
OpenMPの要素は大まかに分けると、指示文・ライブラリルーチン・環境変数の3つが規定されており、開発者がこれらの要素を使って並列処理を指示する形で並列的なソフトウェアを実装することになります。TBBと比べるとOpenMPの方が細かく指定する必要があります。とはいえ、OpenMPを使用した方が従来のスレッドプログラミングよりも簡潔な表現が可能ですのでご安心ください。OpenMPは大変良くできており、慣れれば従来のプログラミング技法よりも素早く並列処理を実装することができるようになります。
今回はOpenMPの一番の基礎である、プリプロセッサディレクティブを指定することで行うOpenMPのプログラミングスタイル、並列化されるコードの範囲、スレッド数のコントロールの3点についての解説をします。
文章での説明は退屈だと思いますので、次項から早速サンプルプログラムを提示してOpenMPの説明をしていきます。
はじめてのOpenMP
一番最初は簡単なプログラムを作成するのがよいでしょう。そこで、OpenMP版のhello worldプログラムを作成しました。
#include <stdio.h> #include <omp.h> int main() { #pragma omp parallel printf("Hello, OpenMP!\n"); return 0; }
このプログラムをデバッグ実行して画面を見て下さい。コンソール画面上に「Hello, OpenMP!」と表示されます。しかし、メッセージが一つしか表示されませんので、OpenMPが使用されず並列処理されていない事が分かります。
OpenMPを有効化し、並列処理を可能にするために、[プロジェクトのプロパティ]-[構成プロパティ]-[C++]-[言語]のプロパティページで、「OpenMPのサポート」を「はい」にして下さい。理由は後で述べますが、次にソリューションのプロパティで、このサンプルプログラムのプロジェクトを構成をReleaseに変更してからビルドして下さい。
そして、再度デバッグ実行して下さい。今度はコンソール画面上にHello, OpenMP!がCPUのコア数と同じだけ表示されます。これで並列的に処理がされたことが分かります。
先ほど構成をReleaseに変えてビルドした理由は、Debugでビルドして実行するには特別なファイルが必要になるからです。OpenMPをデバッグ構成でビルドするには、「Microsoft.VC90.DebugOpenMP.manifest」ファイルと「vcomp90d.dll」ファイル(VC2008の場合)が必要になります。このファイルはVisual Studio 2008のStandardバージョン以上ならば「C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\x86\Microsoft.VC90.DebugOpenMP」にありますので、実行ファイルと同じ場所にコピーして下さい。そうすれば、Debug構成でも正常に実行できるようになります。
なお、OpenMPを使用して作った実行ファイルを他のPCで使用するには、再配布パッケージが必要になります。OpenMPでソフトウェアを作成する際にはこの点とライセンスに気をつけて下さい。
このサンプルプログラムでOpenMPの基礎的なプログラミングが分かります。まず、omp
ヘッダファイルをインクルードしなくてはなりません。次にプリプロセッサディレクティブのプラグマ#pragma omp parallel
により、コンパイラに並列処理を指示します。プラグマはプリプロセッサディレクティブの一種ですので、OpenMPをサポートしていないコンパイラや、OpenMPを使用しない場合でもコンパイルすることができます。この仕様により、既存のプログラムを修正しやすくなっています。