青柳 臣一 ブログ(趣味系)

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Silverlight] Parallel で最適化してみる例

Silverlight 3 のサンプルを Parallel で最適化してみたという例がなかなかおもしろかったので紹介。

もともとは 「Flirting With Silverlight」 にある Silverlight 3 のサンプルです。
(「ActionScript に比べてどうよ?」 みたいなところから始まっているようですが、そのあたりはここでは割愛)
”Example” が Silverlight 3 アプリへのリンクになってます。
見てもらえばそのままですが、これは WriteableBitmap にパーティクル(点々)を描いてみるというサンプルです。
マウスを乗っけるとグリグリと動きます。

このサンプルを Parallel を使って並列化してみたというのが 「Adding Concurrency Optimization in Silverlight 3」 です。
並列化と言ってもそんなに難しいことはしていません。
まず、.NET Framework 4.0 に追加される予定の Parallel.For をまねて ParallelFor メソッドを作ります。
この ParallelFor メソッドは記事に丸ままコードが載っています。
次に、OnStoryboardCompleted メソッドの中の 2ヶ所のループをこの ParallelFor を使うように変更します。
変更結果も記事に載ってますので、ここでは要点だけ。

まずは、

while (--index > -1) 
bitmap.Pixels[index] = 0x000000;

というループ。
これは WriteableBitmap の全ピクセルを 0x0 で埋める、すなわち、真っ黒に塗りつぶすためのコードです。
これを単に ParallelFor を使ったループに変更します。

もうひとつは

while (null != particle)
{
x = particle.X;
y = particle.Y;
z = particle.Z;
:
}

というループ。
こちらは ParallelFor できるように以下の修正を加えたそうです。

  • w、xi、yi といったループの外で宣言されているけど、実はループの中でしか使っていないというローカル変数をループの中に移動。
  • 元のコードでは particle という線形リストになっていたものをあらかじめ配列に格納しておいてそちらを参照するように変更。

コードを見比べてもらえばわかりますが、並列化できるようにしたって言うだけでそんなに大した変更ではありません。

さて、結果です。
OnStoryboardCompleted メソッドは 1フレーム描画するたびに呼ばれるようですから、この 2ヶ所を並列化しただけでもそれなりに効果があります。
記事前半にある “Silverlight Version, optimized to leverage Concurrency” が Silverlight アプリへのリンクになってます。
このアプリではスライダでいくつのスレッドで並列化するのか指定することができるようになってます。
私の環境だとスレッド数 1 だと 34fps くらい、スレッド数 8 だと 89fps くらいでした。
Core i7 で論理コア数 8 なんですが、スレッド数を 8 にした状態でタスクマネージャで見ていると、きちんとすべてのコアが動いてます。
けど、スレッド数をそれ以上に増やすとなぜか fps も下がって、しかも寝ているコアが出てきます。
うーん、なんかコアをうまく使えてないような。

ということで、スレッド数を多くした時の挙動はアレですが、論理コア数と同じスレッド数にしているときにはかなりのパフォーマンス向上が見込めそうです。
もちろん、論理コアがもともと 1しかないような場合にはオーバーヘッドの分だけパフォーマンス低下があるかもしれませんが。

ちなみに、ソースコードは記事の最後の方にある “Strange Attractor Project” というリンクからダウンロードできます。
大元の記事のコードでは StoryBoard で OnStoryboardCompleted を呼び出すというやり方でしたが、OnStoryboardCompleted メソッドが HandleRendering と改名され、CompositionTarget.Rendering イベントで HandleRendering を呼び出すというように変更されています。
StoryBoard だと最大 fps で動かせないでしょうからね。

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://shinichiaoyagi.blog25.fc2.com/tb.php/211-e2b410d0
この記事にトラックバックする(FC2ブログユーザー)

[C#][Silverlight]WebRequestの同期呼び出し (2)

id:n7shi:20090731:1248967824でMonitorを取り上げましたが、AutoResetEventを使った方が簡単だということが分かりました。詳細はid:n7shi:20090731:1248967824を修正したのでそちらを参照してください。 AutoResetEventについてはParallel で最適化してみる例で紹介されて

  • 2009/08/27(木) 14:30:07 |
  • 七誌の開発日記

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。