OpenMPを使ってみた

OpenMPをVisual Studio 2012 MFCで使ったみたので、その様子をまとめます。

 

なぜOpenMPを使うのか?

はじめに、OpenMPを使う理由について簡単に説明します。

これまでパソコンで演算処理能力はCPUの速さでほぼ決まっていました。

CPUはトランジスタを集積化したもので、集積化が進めば進むほど演算が速くなります。

2006年あたりまで、集積化が進めCPUは指数関数的に速くなりました。

このことを「ムーアの法則」と呼んだりします。

 

しかし、近年、集積化の限界に到達しました。

集積化しすぎて、CPUから熱が大量に発生することが主な原因です。

さらに速い演算を目指すため、CPUを複数つければいいという方針で現在開発が進んでいます。

 

CPUを複数つけたマルチコアでは、プログラムもそれを考慮したプログラムにする必要があります。

CPUが1つの場合は、ある特定の人に仕事をまるなげすればよかったのですが、

CPUが複数の場合は、複数の人に仕事を分けて与える必要があります。

もし、プログラムがある特定の人に仕事をなげるというプログラムになっていたら、指定された人以外の人を遊ばせることになります。

そのため、パソコンの能力を100%活かせないということになります。

 

OpenMPでは、複数の人に仕事をなげるのを簡単にしてくれる道具です。

OpenMPがあれば、マルチコアのパソコンでプログラムが従来の数倍の速さで動くようになります。

今後はコア数が増えると考えられるので、OpenMPを使ったプログラムをつくれば今後もパソコンのスペックが上がると処理速度が速くなります。

以上のことからOpenMPを使用するにいたりました。

MFCでOpenMP使ってみる

さっそく、MFCでOpenMPを使ってみました。

といっても、とても簡単で

「プロジェクトのプロパティ」->「構成プロパティ」->「C/C++」->「言語」

を選択して、

OpenMPのサポートを「はい」にするだけです。

スクリーンショット_081113_101454_AM

これで初期設定は完了です。

あとは、OpenMPを記述していけばOKです。

今回はボタンのイベントに以下のように記述しました。

	double s_time,e_time;
	s_time=clock();
#pragma omp parallel for
	for(int i=0;i<1000;i++){
		Sleep(10);
	}
	e_time=clock();
	CString ss;
	ss.Format("%lf",((double)(e_time-s_time)/CLOCKS_PER_SEC));
	AfxMessageBox(ss);

for文に入ると10msec待ちます。それを1000回繰り返すので、10sec待つことになります。

その後、メッセージボックスで処理にかかった時間を表示します。

「#pragma omp parallel for」はfor文を並列化処理するというOpenMPの命令です。

この一行for文の前に追加するだけで、for文が並列化されます。

並列化の数はパソコンの最大スレッド数に自動的に設定されます。

ちなみに、今回使用したパソコンの最大スレッド数は4です。

実行結果

これで実行してボタンを押すと数秒後に

スクリーンショット_081113_101619_AM

と表示されます。つまり、処理に2.622秒かかったことになります。

ここで、「#pragma omp parallel for」をなくして実行すると

スクリーンショット_081113_101808_AM

となります。プログラム通り処理時間は約10秒となります。

ここでは使用したパソコンは最高で4スレッドの並列化が可能なので処理時間が4倍になりました。

最後に

今回、OpenMPを使用した結果たしかに速くなりました。

しかも、最大スレッド数の数だけ早くなるのでこれを使わないてはありません。

みなさんも、ぜひ、OpenMPを試しに使ってみてくださいね。

(最大スレッド数100以上のパソコンで使ったら楽しいでしょうね)

著者:安井 真人(やすい まさと)