aobench の並列化

Published 07 September 09 04:06 PM | hiroyuk 

CEDEC 2009 での講演の準備中に、レイトレースの C のベンチマーク aobench を教えてもらったので、このベンチマークを Visual Studio 2010 の PPL(並列パターン ライブラリー)を使い、並列化してみました。

レンダリング ループを parallel_for を使って以下のように並列化しました。

void render(unsigned char *img, int w, int h, int nsubsamples)
{

int x, y;
int u, v;

//for (y = 0; y < h; y++) {
parallel_for( 0, h, [&](int y) {
  //for (x = 0; x < w; x++) {
  parallel_for( 0, w, [&](int x) {
    for (v = 0; v < nsubsamples; v++) {
      for (u = 0; u < nsubsamples; u++) {

        …

      }
    }
  //}
  });
//}
});

この並列化によって、ベンチマークの結果は Core2 Quad で2.13秒(直列)から0.64秒(並列)へとそこそこの結果でしたが、結果の画像が次のようにおかしくなってしまいました。

clip_image001

2日ほど悩みましたが、理由がわからず US の Parallel Team に問い合わせると、10分で回答が返ってきました! 変数 u, v がループの外側で宣言され、並列な全タスクで共有されていたのが原因です。最終的に以下のようにループ内での宣言に直すと、正しい画像が得られるようになりました。並列化のワナですね...

void render(unsigned char *img, int w, int h, int nsubsamples)
{


parallel_for( 0, h, [&](int y) {
  parallel_for( 0, w, [&](int x) {
    for (int v = 0; v < nsubsamples; v++) {
      for (int u = 0; u < nsubsamples; u++) {

        …

      }
    }
  });
});

PPLやTPLによる並列化は、スレッドを生成・管理するスレッド ベースの並列化手法に比べ、はるかに簡単に並列化でき、スケーラブルな性能が期待できるのが魅力的です。コードを添付しますので試してみてください。

Filed under:
Attachment(s): ao.cpp

Comments

No Comments
Anonymous comments are disabled

About hiroyuk

マイクロソフト㈱エバンジェリスト。北海道大学理学部物理学科卒。リアルタイム3Dグラフィックスを専門とし、グラフィックスやシェーダに関する技術文章を執筆・講演。 DirectX SDK日本語ドキュメントの開発に携わるとともに、Windows Presentation Foundation プログラミング(オーム社)、Game Programming Gemsシリーズ、リアルタイム レンダリング第2版(ボーンデジタル)、Texturing & Modeling, A Procedural Approach などを翻訳・監修、XAMLプログラミング(ソフトバンク クリエイティブ)を執筆。趣味は薪割り。

Search

This Blog

DirectX 情報

Silverlight 情報

Windows 情報

WPF 情報

並列コンピューティング情報

著書

Syndication

Page view tracker