SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

.NETでマンデルブロ集合を描く(後日談)
――Task Parallel Library/Parallel Patterns Libraryの利用

マルチスレッドでもっと高速化


  • X ポスト
  • このエントリーをはてなブックマークに追加

 前回の記事「.NETでマンデルブロ集合を描く」に引き続き、排他制御の排除とマルチスレッド化による高速化を試みます。Visual Studio 2010 β2を使い、.NET Framework 4.0の新しいライブラリ:TPL(Task Parallel Library)を使ってみます。Visual C++ 10.0の新ライブラリ:PPL(Parallel Patterns Library)版のおまけつき。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 前回の記事「.NETでマンデルブロ集合を描く」では、20年以上前にBASICで書いたマンデルブロ集合描画プログラムの.NETによる再実装を試みました。出来上がったアプリケーションはマンデルブロ集合の全体像を2秒弱で描画できたのですが、僕としては正直期待外れ。当時例えば10時間(=36,000秒)かかったとして、2万倍速くなっているなら1.8秒で描画できる勘定にはなります。だけどね、当時と比べてみればCPUのレジスタ幅は4倍、クロックは4千倍近いし、メモリに至っては数十万倍、加えて当時はBASICインタプリタで動いてたわけで、両者の速度比は2万倍どころじゃないはずなんですよ。

 そこで今回は高速化をねらいます。現在(2009年12月)Visual Studio 2010と共にβ2がリリースされている.NET Framework 4.0では並列化をサポートするライブラリ:TPL(Task Parallel Library)が大きな売りの一つです。このTPLを使ってみましょうか。ついでにVC++10.0での並列化ライブラリ:PPL(Parallel Patterns Library)も。

速くないのはナゼなんだろう

 このアプリケーション、僕の所属するわんくま同盟の勉強会で軽く紹介しました。デモのお披露目とともに計算と描画のからくりをざっくり説明したところ、会場から「GDIで点打ってんの? それじゃ処理時間の多くは描画に食われてんじゃない?」とのご意見。……なるほど。ちょっと調べてみましょう。

 ものは試しにBitmapに点を打つ、すなわちSetPixelしている箇所をコメントアウトし、コンパイル/実行しました。その結果BackgroundWorkerの開始から終了までの所要時間が今まで1,600[ms]だったのが1,000[ms]に短縮されました。3割以上の時間をSetPixelに費やしているわけです。

 マンデルブロ集合の計算はマルチスレッドと非常に相性がいいはずなんです。というのも、ある点に対する計算は他の点と完全に独立していますから、他のスレッドとの同期やリソースの排他制御の必要がなく、各スレッドは無駄な待ち合わせなしにフルスピードでぶん回ることができます。

 ところがそのスレッド内でBitmapにSetPixelしていると話が違ってきます。Bitmapは複数のスレッドから同時にアクセスできませんから、そこにはBitmapというリソースの排他制御、要するに無駄な待ち合わせが生じます。待ち時間が計算そのものに要する時間に比べて十分に小さいならまだしも、先ほどのSetPixelを端折る実験によればBitmapへのSetPixelは相当に重い処理/時間のかかる処理と考えられます。

 前回用いたユースケース風クラス関連図を再掲します(図1)。計算コビト(MandelbrotPlotter)と絵描きコビト(MainFrame)の両者が参照し、お互いの仲立ちをしている方眼紙(SectionPaper)はその内部にBitmapを抱えています。従って絵描きコビトが描画のためにBitmapnにアクセスしている間、計算コビトは計算の結果をBitmapに反映させることができません。

図1 計算コビト・絵描きコビト・方眼紙・色鉛筆セットの関係(再掲)
図1

 また、今回企んでいる並列化による高速化では、計算コビト内の計算ルーチンを複数個立ち上げ、複数の計算を同時に行って高速化をねらうつもりなのですが、計算ルーチンの出力先がBitmapである限り本来独立/並行動作できるはずの複数の計算ルーチンが待ち合わせを行わざるを得なくなります。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
前準備:Bitmapの排除

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4697 2009/12/28 16:27

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング