Syoyo Fujita's Blog

raytracing monte carlo

Category: floating point

HPC 産業の未来とレイトレ

事業仕分けにより、次世代スパコン事業が予算削減されましたね.
まあなんとなーく、私としても 1000 億もなんで必要? と思っていたので、しかるべき結果になったという感じでしょうか.

とまあ現状の感想を述べても面白くないので、今後の HPC はこうなる!みたいな話でもしてみたいと思います.
結果だけまず言うと、HPC の未来は、リアルタイムレイトレがキラーアプリとなるでしょう.

HPC の活用を広げていかなければならない

HPC インサイダーで、HPC の未来を考えているひとと話す機会を最近得ることがあったのですが、
やはり彼らインサイダーも、

「N 体とかタンパク質解析とか、もちろんそれはそれで大切であるが、
やはり HPC を活用していくにはそれでは足りない。もっと皆のためになり役立つものをどんどんとやっていかなければならない.
なので syoyo 君、HPC を使ったリアルタイムレイトレには期待している
(最後の行は意訳)」

と言っておられました.

今回の予算削減は、このようなキラーアプリを提案できなかったことによる理由も多かったのではないでしょうか.

HPC ハードのコモディティ化

CPU はもう x86 でコモディティ化しています.
最近は NVIDIA が HPC 路線へと経営の舵を大きく切り、Fermi によるパーソナル HPC チップを市場に投入しようとしており、
新規プレイヤーの参入により HPC の市場の商業化をさらに押し進めています.
(もちろん、Intel Larrabee の存在もあります)

いままで、
専用 CPU + 専用アクセラレータか、
汎用 CPU + 専用アクセラレータという構成だったものも、
もはや 汎用 CPU + 汎用アクセラレータに置き換わろうとしています.

現時点では、ハードの信頼性や性能という点では、Fermi や Larrabee はまだまだ疑問の余地がありますが、
これらは市場に叩かれて、いずれや堅牢なアーキティクチャになることが見えています.

このような流れでは、もはや HPC のためのハード開発事業は国費でやるものではなくて、
マーケットに任せるのが効率がよくなるでしょう.

もし国費でやるとしても、予算のほとんどは頭脳への振り分けに絞り、
プロセッサ設計やアプリを並列化しやすくするかのアルゴリズムの研究開発に注力し、
ハード製造は TSMC などの製造メーカーにやらせちゃうのがいいんじゃないでしょうか.

ただ、問題は頭脳に投資するとなると、突き詰めると天才数人に投資すればいいということになってしまうので、
多人数の雇用を確保するという効果が見込めなくなるということなんですよね.
ま、その天才数人が、ひらめいたアイデアで新しい市場を作り出し、新しい雇用を創出してくれればいいんですけど.

IO がネックだ

技術的には、HPC はいまは複数のプロセッサを並べて性能を出しているわけですが、
もちろん、単に並べれば並べたぶんだけ速くなるわけではありません.

昔からそうですが、一番の問題はネットワークなどの I/O 速度向上が CPU の速度向上に比べて成長が遅いこと.
そしてこれから、さらに I/O と CPU 演算能力の乖離はどんどんと広まっていきます.
どんなに 1 ノードの演算が速くても、いまじゃ I/O がネックになってしまう.

よって、今後は 1 ノードでいかに演算をこなせるかがカギになるでしょう.
(あ、消費電力もカギになりますね)

とはいえ、やはり 1 ノードで高い計算が行える新規の CPU チップ(ハード)開発は、いまとなっては費用などの面で非常にむずかしい.
そんなわけで、performance per watt がまあまあ高く、
比較的 CPU と密につながっている GPU などのアドオンカードでの演算アクセラレーションに注目があつまっています.
この流れはさらに加速するものと思われます.

NV が グラフィックスから HPC にスイッチしたのも、
近年 Tesla は商業的成功(HPC 系事業は黒字)しているが GeForce は赤字続きであった、
というのもありますが、このような HPC の時流もあるからかもしれません.

個人的には、ARM コアを沢山並べたシステムも面白いかなーと思いますが、
やはりこの場合もノード数がそれなりに増えそうなので、これも I/O がネックになってあまり現実的でないかも.

HPC のキラーアプリはレイトレ

だって、、、

– 大規模データの可視化するならレイトレで奇麗にかっこ良くみせたいでしょう.
– ボリュームレンダリングするならレイキャスでしょう.
– ボリュームも、人体モデルならサブサーフェススキャタリング効果加えたいよね. 仮想手術シミュレーションがよりリアルになるし. やはりレイトレが必要だ.
– 物理衝突計算? レイトレで再近傍探索!
– 映画産業、レイトレで CG 作るのに 1,000 台、10,000 台のレンダーファーム作っているんですから、もう HPC の有効活用みたいなもんでしょ.

おお、なんと HPC と相性がいいのだ、レイトレは!

まとめ

というわけで、まとめると,

– ハードはコモディティ化した. しかし頭脳(ソフト、アルゴリズム)はまだだ(頭脳に投資する余地と価値は十分ある)
– I/O がこれからもどんどんとネックになる. 1 node でどれだけ性能が出せるようなアルゴリズムを見つけられるかが勝負.
– なにはともあれアプリ. HPC でリアルタイムレイトレ!もうこれしかないっしょ!

ま、今回の事業削減が、単なるハコモノを作ることに流れていたカネがこのような方向に流れるようになる追い風になる気が実はしています.
(頭脳への投資に注力、レイトレなどの実用かつみんなのためになるアプリ開発に注力)

実際、今、HPC 野郎と、最近 HPC で(リアルタイム)レイトレをやっていろいろ面白いことができないか、いろいろ道を探っています.

What will happen if realtime raytracing runs on 1P flops computer?

ねんがんの 1P flops コンピュータを てにいれたぞ

ひょんなことから? 1P(ペタ) flops 級の計算機環境を使わせていただけることになりました.
ありがたいことです.

1P flops でリアルタイムレイトレ、リアルタイム G.I. をやったら、どれくらいすごい映像が作れるだろう?
1P flops で lucille のレンダリングをやったら、どれくらい高速にレンダリングできるだろう?

いろいろ妄想は膨らみます…
が、やるなら「こんなレイトレ、はじめて…」みたいな成果を出すことが期待されるので、プレッシャーも同時に感じます.
# 今回も思いましたが、そろそろ本気で、今後の爆発的な(リアルタイム)レイトレ技術者の需要を
# どう解決していくかというのを考えないと感じています.
# レイトレ教育を行い、レイトレ雇用を生み出し、レイトレ報酬を支払い、レイトレ経済圏をどう確立していくか…. 難しい問題ですね.

Fermi has over 1T DP Flops?

http://www.nvidia.com/object/fermi_architecture.html

– 1/2 speed double precision
– IEEE754-2008 compliant
– 1T DP flops or more?

これも、「おお、ブラボー!」な感じですね.
特に NV のほうは ATI よりも HPC 用途を重視している感じがします.
倍精度が単精度の 1/2 で出来ますし.
正確な数字は出ていませんが、 Radeon と比較して推測する感じでは、1T DP flops くらいになるんじゃないかと思っています.

オフラインレイトレも GPU(や LRB などのアクセラレータ)で高品質を保ったまま、
高速化させることも実務的に出来てきそうです.
OpenCL などの GPU を叩く API や言語の標準化もすすんでいますしね.

このような形のレンダラが本格的に出てくるなら、ソフトウェアの対応とハードが普及してくる 2010 年あたりでしょうか.

ただ、Fermi の発表と同時に iray も発表していますが、
iray は、VRay RT などの他製品もそうですが、
全部プレビュー用な感じでしか使えなさそうなのが残念です.

lucille の場合は、GPU に対応するならば、
カスタムシェーダも動いたり、モーションブラーもアクセラレートできるようなアーキティクチャにしますね.
(もちろん大規模シーンもメモリ転送をうまくやって対応します)

Radeon HD 5870 has 544 DP GFlops

(via twitter)

http://pc.watch.impress.co.jp/img/pcw/docs/317/309/html/kaigai12.jpg.html

– double 精度で 544 Gflops(およそ  Core i7 の 10 倍)
– IEEE754-2008 互換

Spec を見る限りでは、「おぉ、ブラボー!」
GPGPU による、lucille のようなオフラインレイトレレンダラのアクセラレーションに本格的に使えそうです.

CPU での演算と比べて GPU で計算させても double 精度でも誤差が発生せず、
(double 精度でもきちんと IEEE754 互換であれば)
かつ CPU の 10 倍ほどの(理論ピークでの比較ですが)浮動小数点パフォーマンスがあるわけですから、
オフラインレンダラのような精度が求められつつも高速化したいというアプリに向いていると思います.
shared memory も GeForce より多いサイズを積んでいるようなので,
たとえば CUDA ベースのレイトレカーネルも Radeon HD 5870 で問題なく動きそう.

ただ、ATI はどちからというと既存グラフィックス性能重視、NV は汎用演算重視らしいので、
CUDA レイトレのように比較的分岐やランダムアクセスが多いカーネルは、
もしかしたら Radeon ではうまくパフォーマンスが出ない可能性もあります.

いずれにせよ、まずは OpenCL 対応を!… という状況ですね.
(待てないなら Brooks? でやる手もある… のかな)

World’s first SIMD ray-triangle intersection with ARM/NEON

I’ve wrote possibly world’s first SIMD ray-triangle intersection code with ARM/NEON instruction.

The code runs finely on iPod touch 3G(ARM Cortex) and iPhone 3GS.
The performance on iPod touch 3G is around 348 cycles per isect4().
# of assembly instruction of isect4() is around 140, thus the CPI = 348/140 = 2.48, which is not an efficient number for me(CPI should be near to 1.0).

Note that there’s still a room to optimize the code.
e.g. use fmad instruction instead of fadd/fmul combination.

Related articles

– SIMD ray-triangle intersection in Intel/AVX
http://lucille.atso-net.jp/blog/?p=649

– SIMD ray-triangle intersection in OpenCL
http://lucille.atso-net.jp/blog/?p=910

[Google groups] SIMD-cafe for SIMD lovers

なぜ SIMD が重要か

プロセッサのクロック数は頭打ち…
マルチコア化ではコアが増えるたびにコア間の通信がネックになる問題がある.
専用プロセッサを作るにも, 固定したアルゴリズム&量が出ないとビジネスにならないので,
やはり CPU 的にソフトなプロセッサが求められる.
一方で、エコ時代であるので省電力が求められる.
そんな HW の制約の中で、SW(アプリ)は富豪的プログラミングで HW の向上に頼るだけでは対応しきれなくなってきています.
特に認識処理、グラフィックス、データベース処理でパフォーマンスを出していくことが求められている.

このような、現在のプロセッサ(半導体)の技術的壁やプロセッサデザインの収益モデル(ビジネスモデル)を考えると、
特に SIMD 演算器とその活用が重要になってきます.

実際, x86/AVX(wider SIMD), iPhone 3GS(ARM/NEON), Atom/SSE が登場してきています.
アプリを SIMD 最適化する必要性は今後また重要になってくるでしょう.
(SIMD 最適化の最初のブームは、 MMX/SSE/SSE2 の出てきた 2000 年頃でしょうか)

しかし、どんなにコンパイラが賢くても、効率的な SIMD コードを自動で吐いてくれるのはまだまだ難しい.

そこで、プログラマがいかにアルゴリズムを SIMD フレンドリーにするか、
SIMD 演算器をいかにまく使ってプログラムを最適化していくかが、
今また大きく求められている、そんな気がしています.

また、ときどき SIMD 野郎と話すことがあるのですが、
結構みんな「ほかに SIMD のことを濃く話すことができるひとが居なくて…」
と言われることもあり, SIMD 野郎のための google groups を作ってみました.

SIMD cafe
http://groups.google.co.jp/group/simd-cafe

SIMD 野郎の参加をお待ちしております.

approximate double precision division using SSE2

SSE 命令には rcppd なる、double の逆数を近似で求める命令はありません(少なくとも SSE4 までには).
float の場合には rcpps 命令が存在し、これは 1.0 / a の近似を高速に求めることができます.

なぜ rcppd が無いのか?

rcp では、内部では除算テーブルを引くだけの実装になっているようです.
そして、実際のところ、逆数を求めるにはそれほど大きなテーブルが必要無いことが知られています.
(詳細は「ディジタル数値演算回路の実用設計」あたりを参照してください)

なのできっと、double 用にテーブルを用意するよりも、
「一旦 double を float に変換してから rcp を呼び、その結果をまた float から double に変換すればいいんじゃね?」
という考えなのかもしれません.

実際 rcppd2ps, rcpps などで検索したら、上記を行うなんともビンゴなコードが!

http://yoffy.dyndns.org/trac/yofcpp/changeset/518/trunk/yoffy/simd_type/sse2_double2.hpp

Newton 法込みで、44bits ほどの精度だそう.
というわけで、これをベースにして、divpd と cvt/rcpps + Newton 法の比較をとってみました.

ベンチマークソースコードはこちら.
http://gist.github.com/163957

Core2(Merom) 2.16GHz の結果では以下のようになりました.


Macintosh-3: $ gcc -O3 -msse2 -mfpmath=sse main.c
Macintosh-3: $ ./a.out
[SSE approx div] 0.161568 secs
[Scalar div] 0.820053 secs
SSE ver is 5.075590 times faster.

cvt/rcp で近似除算を求めるほうが、divpd で除算を求めるよりも 5 倍早いという結果になりました.
Nehalem だと、divpd, divsd のレイテンシ/スループットが向上しているので、
これよりも差は縮まるかもしれません.

RtInt and RtFloat have enough precision there days?

RenderMan の仕様では、整数データは RtInt, 浮動小数点データは RtFloat
で表現され、これらはそれぞれ C 言語でいう int, float に対応しています.

もちろん、RtInt, RtFloat は define されているものなので、
long, double に変えることもできなくは無いのですが、
RIB や DSO などの既存アプリなどとの互換性を考えると
一旦定義してある型を変えることは非常に困難です.

で、int(32bit 整数), float(32bit 浮動小数点)ってそろそろ限界じゃね?ってお話.

まず、RtInt を考えてみましょう.
RtInt はたとえばポリゴンの定義において頂点インデックスの定義などに使われます.

RtInt の場合、2^31 の頂点インデックス数が表現の限界になります.
この数字により表現できるのは、およそ 700 万ポリゴンほどになります.
現在の CG 表現の複雑性を考えると、Polygons, PointsPolygons
で表現できる 1 プリミティブのポリゴン数の限界が 700 万ポリゴンというのは、
そろそろまずいんじゃないか?と思います.もってあと 2, 3 年かな.
まあ Polygon の定義を二回のコールに分けて対応とかできなくはないですが、
そのような処理をエクスポータなどに書くのは面倒くさいですよね.

つづいて RtFloat.

まあシェーディングは float の精度でもまだいけるかなーという感じですが、
ジオメトリデータはそろそろ double でないと精度不足じゃないでしょうか.
特に地形などの巨大シーンを扱う場合.
DelayedReadArchive とか、グリッドで切って分割レンダリングとかで精度を稼いで
対応できなくはないですが、まあそんなワークフローを作るのは面倒くさいですよね.

そんなわけで、lucille は RtInt は long(64bit int)、RtFloat は double にしたいなーと思っています.
ただそれだと他 RenderMan 互換レンダラとの互換性が取れなくなるので、
別 API で long と double を受け付けるものを用意するのが現実的でしょうか.
PointsPolygonsEx みたいな感じで
(うーん、しかし Win32 API みたいで格好良くないですね)

結論

さすがに RenderMan はフォーマットが 20 年前に定義されていることもあり、
いろいろなところで限界が来ています.
今回はその中で精度は足りるか?という話でした.
やっぱいずれは lucille 用に次世代対応な独自フォーマットを定義するようにしたいですね.

Good introduction and history on Numerical Computation with Guaranteed Accuracy

http://w2.gakkai-web.net/gakkai/ieice/vol6pdf/vol6_09.pdf


This is a must see material on numerical computation.

The document describes a history of Prof. Oishi’s research on numerical computation with guaranteed accuracy.

Prof. Oishi is well known researcher on Numerical Computation with Guaranteed Accuracy(GA is based on interval arithmetic and it includes error free computation, faithful computation, etc)

Theory of Guarantted Accuracy is vital for graphics application for example accurate ray tracing, physics and geometry processing.

[Ja]

lucille のレイトレコアもそろそろしっかりと精度保証して演算誤差をバウンドしたいと思っていて調べていたら見つけました.

大石先生の精度保証に関する研究のイントロダクションと歴史についてかかれたドキュメントです.
短くまとまっていて、また研究がどのような発展を辿ったのかよくわかってとても役に立ちます.

ところで、精度保証の基礎となるアルゴリズムの TwoProduct って FMA(一回だけの丸め) がないと 17 fp 演算も必要なんですよね.
x86 もきちんとした FMA を実装してくれたら(AVX や SSE5 の FMA は二回の丸めなのでダメ), 結構精度保証のテクニックも気軽に使えるものになると思うのです.

iPhone 3G = 4.8 GFlops?

genki さんと一緒に,
iPhone や iPod touch に載っている ARM プロセッサの VFP(ベクトル浮動小数点ユニット) について調べていました.

とりあえず現時点で理解したこと.

VFP は一度に演算するベクトル長を指定できる.

浮動小数点ステータスレジスタの LEN ビットにベクトル長を書き込むことで、
FP 命令 (fmuls など)はそのベクトル長ぶんの演算を一度に行うという、ちょっと変態なアーキになっている.
通常の FPU としての利用だと、ベクトル長 = 1 ということ.
ベクトル長は単精度だと最大 8 個、倍精度だと 4 個まで設定できる.

ただし、ベクトル長ぶんのレジスタバンク(レジスタペア)を消費する.
単精度だと全部で 32 レジスタ(s0 ~ s31)、倍精度だと 16 レジスタ(d0 ~ d16)あるけど、
たとえばベクトル長 4 なら、各命令のオペランドは [s8, s11] などという風に 4 個レジスタを消費する.
つまり、こんな感じの動作モデルになる.


# ベクトル長  = 1 の場合:
fmuls s8, s9, s10    ; s8 = s9 * s10

# ベクトル長 = 4 の場合:
fmuls s8, s12, s16  ; s8  = s12 * s16
                    ; s9  = s13 * s17
                    ; s10 = s14 * s18
                    ; s11 = s15 * s19

また、レジスタすべてをベクトル演算用に使うことはできなくて、
単精度の場合、s0 ~ s7 のレジスタバンクはスカラ演算のみに使うことができる.
つまり、単精度でベクトル長=4 のときだと、実質的には 6 SIMD レジスタ(4×6=24) しか扱えない.
倍精度に至っては、ベクトル長=4 だと 3 SIMD レジスタしか使えない.
パイプライン実行で命令レイテンシを隠してパフォーマンスを出すことを考えると、
6 レジスタでぎりぎりなんとかストールなしになるかも..、というところか.

VFP で SIMD 演算のプログラミング

通常の浮動小数点演算コードは、iPhone SDK の gcc-arm により、
ベクトル長=1 の条件で浮動小数点命令にマップされるけれども、
ベクトル長 = 4 などの SIMD 演算命令出力はサポートされていない.

llvm の ARM バックエンドも、 型の演算は、単純に 4 回の fp 演算に展開されてしまう.
また gcc で C 言語から VFP 命令を直接扱える intrinsic 関数のインターフェイスもない.
(VFP の後発の NEON だと, intrinsic 関数がある).

なので、現状 VFP で SIMD 演算をしたかったら、アセンブラでプログラミングするほかないようです.
ここはやはりオレコンパイラバックエンドを書ければ理想ですね.

VFP 演算ピークはいくら?

VFP には FMAC(積和命令) があり、レイテンシ/スループットは 1/8 である.
(タイミングは、ベクトル長には関係ないのかな?)

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344c/ch16s07s01.html

ベクトル長 = 4, 単精度のときを考える.
iPhone 3G だと 600 MHz くらいのクロックのようなので、 VFP もこの速度で動いているとすると、

0.6(GHz) x 2(FMAC) x 4(SIMD LEN) = 4.8 GFlops

となります.
仮説が正しければ、ポテンシャルとしては、
iPhone 3G は Core2 2GHz の 1/4 くらいの浮動小数点パフォーマンスがあることになります.

けっこう、iPhone でメガデモというのも可能性としてありそうかな?… 🙂