2012/12/11

OpenMPによる並列化

これがこいつの……本当のチカラなのかッ!?!?

よっぽどへんてこなのじゃない限り僕らの使ってるパソコンはマルチコアなので、
処理を並列化すればコアの数だけ倍速になる。(理想)
4コアなら4倍速だ!!!(理想)
パソコンの本当の力を知ることができるぞ。

並列化を使わないゴリラは100000頭中0頭だ。


OpenMP

ここではOpenMPでの並列化について書く。

なお、OpenCV2.4 ではOpenMPではなくTBB(より新しい)が同梱されている。
http://imagingsolution.net/program/opencv/opencv2-4-dynamic-downlaod-install/
なのでOpenMPではなくTBBで並列化をやってもいいと思う。
http://sourceforge.jp/projects/hpc-parallel/wiki/%E4%B8%A6%E5%88%97%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86_all
状況に応じて適切な並列化技術を使い分けよう
以上、マルチスレッド、OpenMP、TBBを使用した並列処理の実装について紹介してきたが、それぞれに特徴があることが理解いただけただろうか。マルチスレッドによる実装はもっとも柔軟ではあるものの、実装の手間やスケーラビリティに欠ける一方、OpenMPによる実装は手軽で、かつスケーラビリティも確保できる。また、TBBはOpenMPよりも柔軟だが、マルチスレッドの場合ほどは実装が複雑にならない、ちょうど中間に位置するものとも言えるだろう。

OpenMPはforループの前に1行書き足すだけで並列化できる。
ただ、forループの中で同じ変数をいじったりしないよう、
自分で気をつけなくてはいけない。

導入

参考サイト:
http://tech.ckme.co.jp/openmp.shtml
http://blender.jp/modules/newbb/viewtopic.php?viewmode=thread&topic_id=871&forum=4&post_id=6746

  1. Visual C++ 2008 Express をインストール(2010には omp.h, ompassem.h, vcomp.lib, vcompd.lib がないため)
  2. http://www.microsoft.com/en-us/download/details.aspx?id=11310 をインストール(64bit版のvcomp系のdll がないため。C:\Windows\winsxs\ のamd64がつくファイルにvcomp90.dll が入るはず。)
  3. (以下、プロジェクトごと) VC++ 2010 でプロジェクトを開くor作る
  4. 構成をReleaseに設定、プロパティ→構成プロパティ→C/C++→言語→OpenMPのサポートを「はい」に設定
  5. C/C++ で追加のインクルードファイルの最後にVC++ 2008 のincludeファイルを追加
    C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include
  6. stdafx.h など、どこかのヘッダファイルに以下を追加(1番目が64bitプログラムの場合、2番目が32bitプログラムの場合)
    // 64bit
    #ifndef _DEBUG
      #pragma comment(lib,"C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\lib\\amd64\\vcomp.lib")
      #include <omp.h>
    #endif 
    
    // 32bit
    #ifndef _DEBUG
      #pragma comment(lib,"C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\lib\\vcomp.lib")
      #include <omp.h>
    #endif
  7. 並列化したいfor文の前に #pragma omp parallel for と記述する、など。
以上。
あんまりないと思うが、デバッグモードでも並列化したい場合はぐぐれ。

最後に

  • できないよ: 並列化ループでvectorにPUSH☆
  • できないよ: 並列化ループでBREAK☆(continueならOK)
  • できないよ: 最大値をエレガントに求める☆(それぞれのコアごとに最大値を求めて、最後にそれらの最大値をとる)
  • 分割するコストがあるから単純に高速化できるわけじゃないし、
  • 全CPUの使用率を100%で維持するのは、並みのゴリラには難しい

0 件のコメント:

Related Posts Plugin for WordPress, Blogger...