Syoyo Fujita's Blog

raytracing monte carlo

Month: March, 2009

第二回 LLVM 勉強会参加ありがとうございました.

少々遅れましたが、第二回 LLVM 勉強会、参加された方ありがとうございました.
miura さんには遠路はるばる来ていただき yarv2llvm について世界初の講演していただきました.
非常に貴重な勉強会だったと思います.

当日の資料は以下のリンク先にて入手できます.

第二回 LLVM 勉強会

ところで、最近は MacRuby も LLVM を使って ruby を高速化しようとしていたり、
Python も unladen-swallow で LLVM を使って Python 実行を高速にしようとしていたりと、
だんだんと動的言語も LLVM で早くしていこうみたいな動きが出てきていますね.

lucille v.s. PRMan: Updated

I misinterpreted the value of ShadingRate.
ShadingRate 0.5 means that shading point will be generated 2 points per pixel, not 4(2×2) points per pixel.

Thus I matches the condition same with lucille, by setting ShadingRate 1.0 and PixelSamples 1 1(1×1 subsamples/pixel).

Here’s the updated condition for rendering lighthouse scene:

– 512×512 pixel
– 2 threads(2 cores)
– gather() based AO shader: 256 gather rays
– PixelSamples 1 1, ShadingRate 1

And here’s the rendering result and time.

lucille_256_1×1.png
(1m, lucille)

prman_256_1×1.png
(6m, PRMan)

3delight_256_1×1.png
(12m, 3Delight)

lighthouse_fixed.png

Conclusion

lucille is 6x faster than PRMan, Yey!
– lucille is 12x faster than 3Delight, Yey!

[Ja]

前回までの lighthouse でのレンダリング時間比較ですが、比較が正しくありませんでした.
ShadingRate 0.5 は pixel あたり shading 点を 4 個(2×2) 作ると間違って解釈していました.
正しくは 2 個作ります.
ShadingRate は”面積”を指定するのでした。”辺の長さ”と間違って解釈していました.

よって PRMan, 3Delight の結果は 2×2 = 4 samples/pixel の 2 倍は少なくシェーディング処理が生じていることに.

そこで PixelSamples 1 1, ShadingRate 1 として、1×1 subsamples/pixel 相当にして再測定しました.
(そのため gather samples は 2×2 subsamples x 64 = 256 に上げた).
PRMan の結果については soichi_h さんにご協力いただきました.

結果は lucille との差が大きく開くことに.
PRMan と 3Delight は、およそレンダリング時間が ShadingRate 0.5 の時の倍となりました.
(これはこれで期待する結果に)

いやー、自分で言うのも何ですが、なんだ、lucille の圧勝じゃないですか.
やはり Reyes ベースレンダラには未来は無いと思います.

あとはこの速度差を保ったまま、レンダラとしての機能を PRMan レベルまで拡充させたり、
大規模シーンでもメモリを効率的に使って安定にレンダリングするなどの機能を追加すれば、
(レイトレだからメモリを多く消費するというのは実装者が怠慢なだけです)
PRMan はツブせそうです 🙂

ただ、ひとつ気になる存在が.
V-Ray が以外と最近ゴイスーなんですよねー. レイトレも速いし.
真の敵(?)は実は V-Ray じゃないかと最近思うようになっています.

lucille v.s. PRMan: Performance comparison

(updated)

OK, next challenge is fighting the giant: PRMan.

soichi_h kindly measured rendering time of lighthouse scene and Mandelbrot shader in PRMan(version 14.2) and reported numbers and rendered images to me.

lighthouse scene with AO

The setting is same in the previous article, but # of gather samples are raised from 32 to 64 in this case.

lucille_lighthouse_64.png
(lucille, 62 secs, Core2 2.16GHz x 2 cores)

lighthouse_prman.png
(PRMan, 146 secs, Core2 2.53 GHz x 2 cores)

lucille_prman_lighthouse.png

Even though PRMan was executed in different, higher-clocked machine(Core2 2.53 GHz), still lucille is about 2.3x faster than PRMan!
(If we normalized the CPU clock for both results, lucille is about 2.7x faster than PRMan)

Mandelbrot shader performance

mandel_lucille_gamma1.png
(0.43 secs, lucille(JIT shader), 1 core)

mandel_prman.png
(3 secs, PRMan, 2 cores)

mandel_lucille_prman_graph.png

Even though PRMan was running on 2 threads(2 cores) whereas lucille was 1 thread, still lucille’s JIT shader is 7x faster than PRMan!

Summary

To summarize the performance comparison of lucille and PRMan with lucille v.s. 3delight(lighthouse, Mandelbrot), I could say,


lucille(fastest) >> PRMan 14.2 >= 3Delight 8.0.1(slower)

As previously stated, lucille still has much more room for optimization.
If I carefully tuned up lucille source code, lucille would become 5x ~ 10x faster than PRMan, hehe 🙂

[Ja]

soichi_h さんから PRMan 14.2 で lighthouse シーンと Mandelbort シェーダを走らせたときのレンダリング速度結果をいただきました.ありがとうございます.

PRMan, なかなか手強かった(?)ですが、それでもまだ lucille が lighthouse シーンでは 2.3 倍程度, Mandelbrot シェーダでは 7 倍、PRMan より速いという結果になりました.
(実行したマシンの環境が違い、PRMan を実行した環境のほうがクロックが高いので、クロック比を合わせるともう少し差がでます)

—-

前にも書いた通り、lucille はしかしまだまだ最適化の余地があります.
アルゴリズムはそのままでコードの最適化だけしたとしても、少なくともあと 2 倍は高速化できると見込んでいます.
そうすれば lucille は PRMan, 3Delight の 5 ~ 10 倍速い、という風に言えるようになりそうです.

Larrabee New Instruction in C intrinsic function

(via ompf.org)

http://software.intel.com/en-us/articles/prototype-primitives-guide/

LNI(Larrabee New Instruction) の C イントリンジック関数定義(とその SW 実装)が出てました.
これは C ソースレベルでの LNI のシミュレータとして使うことを想定しているようです.

_M512 型とか、_mm512_add_ps() とか、ほとんど SSE や AVX の C イントリンジック関数と同じですね.

実際のアセンブラ命令名も AVX のような形になるようで(vaddps とか)、単に AVX の 512bit 版という感じになるっぽい.
LNI についての詳細は今週末の GDC 2009 で公開されるので、そちらも注目ですね.

[Solved] Differences on gradation in mandelbrot shader.

Why the rendering result of mandelbort shader differs is that lucille’s result was GAMMA CORRECTED.

lucille_mandel1.png
(gamma 2.2, rendered by JIT shader)

mandel_gamma_10.png
(gamma 1.0, rendered by JIT shader. Same result with 3delight)

Wow, how different the image are!

[Ja]

lucille(JIT shader) と 3delight で mandelbrot shader の結果が違う理由が解決しました.
その理由は JIT shader の方は gamma 2.2 で結果を補正していたから!(なんでそうしていたのかは忘れた)

gamma 1.0 に戻したら、3delight の結果と同じになりました.
というわけで Mandelbrot 演算している量はやはり同じでした.

しかし gamma が違うとこんなにも結果が違うとは… gamma、恐るべし.

[Paper, ICFP09] Dataflow Optimization Made Simple

Dataflow Optimization Made Simple
John Dias, Norman Ramsey, and Simon Peyton Jones, and Satnam Singh, ICFP 09.

コンパイラが行うデータフロー最適化は、実はコンパイラの教科書で解説されているほど難しくはなく書けるんだよ、というのを示しているらしい.
論文で提案されているデータフロー最適化のフレームワークは、実際に GHC(Haskell コンパイラ)の新しいバックエンドとして採用されているとのこと.

そのためデータフロー最適化フレームワークの実装言語は Haskell で、ターゲットの言語は C–(cminusminus).
C– は GHC の中間言語(の中でも下のほうあたり?)として使われている言語. 見た目は C に近いけど、LLVM IR のようにコンパイラが扱いやすい形式となっている.

論文では、提案するデータフロー最適化のフレームワークを使って以下のような最適化や解析が簡単に実装できることを示している.

– 生存解析(Liveness Analysis)
– 定数畳み込み(Constant Folding)
– 使われない代入の除去(Dead-assignment elimination)

そして、ここが今回の論文のキモであろう部分: コンパイラ書きにとっては、このフレームワークを使えば、以下の 3 つを提供すれば好みのデータフロー最適化を実現できるらしい.

– assertion ( C の assert() とは異なり、 x = 4 などの fact)
– transfer function
– rewrite function

感想

んー、しかし「簡単にできる」と言われても、
私の現状の Haskell の知識では論文に乗っているだけの Haskell コードだけじゃどうにも理解できないです.
GHC のソースを見れば判るかなぁ?

しかしデータフロー最適化は JIT Shader の今後のさらなる最適化のためにはどうしても避けられない道なので、
うまいやり方(フレームワーク, デザインパターン)があるのなら、それを利用するに越したことはないと思っています.
そのため、この論文の提案するフレームワークには注目しています.

まずは理解できるように、こちらがもっと Haskell のことを学習しないといけませんね.

lucille v.s. 3delight: Shader performance

OK, next is the comparison of (programmable) shading perfomance.

Condition

– Mandelbrot shader
– 1 shading sample per pixel
– Rendering 512×512 one quad polygon
– Rendeting with 1 thread(1 core)

For lucille, JIT Shader was used.

Here is the mandelbort shader code.

Result

lucille_mandel.png
(0.43 secs, lucille JIT shader engine)

mandel_3delight.png
(5 secs, 3delight 8.0.1)

There’s a differences on gradation, but I believe same amount of shader execution was done for both case.

Surprisingly, lucille’s JIT shader could execute mandelbort shader 11x faster than 3delight!
(exclude time for compiling mandelbrot shader)

[Ja]

レイトレのパフォーマンス比較の次として、シェーダのパフォーマンスも lucille と 3delight で比較してみました.
lucille の方は正確には、現在はまだ統合されていなくて別プログラムとなっている JIT shader engine を利用.

結果はなんと lucille が 3delight に比べて 11 倍.
(シェーダコンパイル時間は双方除く)

LLVM のおかげ、というのもありますが、
インタプリタ実行(3delight はインタプリタ実行のはず)よりもネイティブ実行のほうがやはりパフォーマンスが出るという予測は正しかった.
(インタプリタでも reyes のコヒーレンシを生かして SIMD 実行すればインタプリタのオーバーヘッドは無視できるというのがインタプリタ派の意見)

なんかシェーディング結果にちょっと違いがあるのですが(グラデーションまわり)、
演算量はどちらも同じはずなのでさほどこれはパフォーマンスとは関係ないと思うので、気にしないことにします.

「圧倒的じゃないか、我が JIT shader は…」

lucille v.s. 3delight, continued.

I measured raytracing performance of lucille and 3delight again with a moderately complexed scene(200K polys).

The setting is same as done in previous article, except for # of samples in gather shader which was reduced from 128 to 32.

lucille_lighthouse.png
(lucille, 38.5 secs)

delight_lighthouse.png
(3delight, 213 secs)

lucille_delight_lighthouse_chart.png

In this case, lucille is about 5.5x faster than 3delight, hehe 🙂

[Ja]

こんどは少し複雑なシーン(20 万 poly)で lucille と 3delight のレイトレのパフォーマンス比較をしてみました.
結果は 5.5 倍ほど lucille のほうが高速(RIB パース処理とか全部込みで).

ふむふむ、3delight は複雑なシーンになるほどレイトレのパフォーマンスのスケーリングは悪くなるようですね.
前回も書いた通り、まだまだ lucille のレイトレエンジンは高速化の余地があります.
なのでそこんとこ頑張ってあと 2 倍高速化すれば、「lucille のレイトレパフォーマンスは 3delight の 10 倍!」と言えるようになりますね.

lucille v.s. 3delight: raytracing performance.

lucille is near to next release and I am freezing features and cleaning up codes.
Since codebase of lucille become stable for next release, I did small benchmark comparison with lucille & 3delight, especially for comparing raytracing performance.

The condition is ambient occlusion scene(using naive but true raytracing for both renderer).

lucille_ao_speed_test-2.png
(lucille, 57 secs)

3delight_ao-1.png
(3delight 8.0.1, 134 secs)

Condition

– Intel Mac, Core2 2.16GHz
– Rendering with 2 threads(2 cores)
– 512×512 pixel output.
– 2×2 subsamples(ShadingRate 0.5, PixelSamples 2 2)
– 128 gather rays per shading point.
– “box” 1×1 filter

Scene data

Here’s RIB and RSL used to render the image.

lucille’s raytracing is 2x faster than 3delight’s one.

The result shows lucille is about 2.3 times faster than 3delight for identical rendering condition.

In case of lucille, unfortunately, lucille has not yet been merged with JIT shader engine, thus gather shader was hard-coded in lucille. But I guess there would be a small performance differences when gather shader runs onto JIT shader engine merged with lucille, compared to hard-coded shading.

It is stated that 3delight is fast and employs fast raytracing, but still lucille is 2x faster, hehe 🙂
More to say, there’s still much room for optimization in lucille’s raytracing engine.

[Ja]

lucille のコードベースもひとまず落ち着いてきたので、ちまたではレイトレが早いと言われている 3delight とレイトレの速度を AO 処理で比較してみました.
gather() シェーダを使って、両方とも確実に普通のレイトレが行われるようにしています.
「確実に普通の」、というのは、たとえば occlusion() などでやってしまうと、たとえば pixie ではレイトレでなく近似で AO を計算したり放射照度キャッシュを使われてしまったりするため、確実にシェーディング点あたり一本一本レイトレをする方法で、という条件に設定した、ということ.

各レンダラの画像は目視レベルですがほぼ同じなので、同じ量のレイトレ処理がされていると見なしていいでしょう.
lucille は pure raytracer なので ShadingRate は関係無くて PixelSamples だけしか見ていないのですが、
3delight は reyes + raytracing ですので ShadingRate = PixelSamples としないと、同じサンプリング量 == 同じシェーディング量になりません.
(ま、ほんとは raytracing context でも ShadingRate は考慮しないといけないのですけどね… ただ、ShadingRate を指定しなくても自動で最適 rate でシェーダサンプリングできるようにしたい. いくつかアイデアはあります)

あと、lucille はしかしまだ JIT シェーダが本体に組み込まれていないので、今回はハードコードなシェーダを利用しました.
(が、JIT シェーダで実行したとしても、ハードコードとほぼ同じ速度になるでしょう)

結果

結果は lucille のほうが 3delight に比べて 2 倍くらい早い.
激的に lucille のほうが早い、というわけではなかったのでちょっと残念です…

ただ、lucille の方はレイトレ処理についてはまだまだ無駄に処理している部分が多いので、
そこをちゃんと最適化すれば 3delight に対して 5 倍くらいにはなるかなぁと思っています.
(パケトレとか、アルゴリズムが根本から変わるという高速化をしなくても)

[緊急告知] ヤッターマン + ドラゴンボール鑑賞会 3/14(土)

ゴ、ゴゴ、ゴゴゴゴ、、、    ゴゴ、ゴゴゴ、、、  ゴ

    ゴゴ、、、  ゴ、、

  ゴ、、、    ゴゴ、ゴゴ、、、、、  ゴ、、、、

突然ですが、Philo 式とコラボが実現しました.
3/14(土曜) にヤッターマン + ドラゴンボール鑑賞会オフを行います. 14:30 渋谷集合になります.
CG 野郎で都合の付く方は 3/14 10:00 くらいまでに syoyofujita @ Gメールアドレス までご連絡ください.

# ただしヤッターマンは超人気らしいので、チケットとれない可能性があります.