デスクトップの暗黒面

実際に過去の GDI プログラミングをされたことがある方が,Windows XPWDDM 環境の Windows Vista で実験すれば,Device Dependent Bitmap,通称 DDB の振る舞いが以前と全然違ってしまっていることに気付くだろう.
要点だけを言えば,DDB のパフォーマンス特性が DIB (Device Independent Bitmap) にそっくりになったということだ.

以下何の役にも立たない暗黒雑学

(注:これを読んでも「Vista の 2D 描画は速くなりません」.が,少しだけ世界の絡繰りが分かるかも知れません.基本的には昔の事情をあまりよく知らない開発者向けに書いています.って私も昔のことは全然知らないのですけど.まあ分かる範囲で書いてみました)

DDB は,ドライバ依存の正体不明なビットマップ,というのが定義だが,ぶっちゃけて言えば VRAM 上のサーフェイス(ただし作りすぎるとメインメモリに待避?),というのが当時の「常識」であった.DDB 間の BitBlt が CPU 律速になって何年経っていただろうか.思えば当時から既に DDB 間の GDI BitBlt (Blt は Block Transfer の略.いわゆる矩形転送)は狂っていた.下手なベンチマークを作ってしまうと,Pixel Fill Rate (1秒間に描画することができるピクセル数)が転送する画像サイズに比例するように見えるのだ.
何のことはない,よく見てみると 16×16 だろうが 128×128 だろうが 512×512だろうが,単位時間に呼び出せている BitBlt 回数が同じことに気付く.呼び出し回数が同じなら,当然スコアは画像面積のみに比例するだろう.
つまり,GPU のパイプが太すぎて,CPU の仕事投入速度が追いついていないことになる.この投入回数の上限は同じタイプの CPU なら概ねクロックに比例するので,21 世紀に至っても,一部の 2D ベンチマークは,CPU クロックに比例するという変な現象が見られた.

Direct3D でも同様の現象は既にあちこちで起こっているが,元々バッチ処理の投入を意識していた API だけに状況はましである.Microsoft や GPU ベンダ各社による,小さなバッチがいかに罪深いことであるか啓蒙キャンペーンが功を奏しているのかもしれない.Direct3D の世界には「小さなバッチ(処理),カッコワルイ」みたいな独特の雰囲気がある*1SQL Server での「カーソル,カッコワルイ」みたいなものだ.

一方で,GDI には Device Independent Bitmap,いわゆる DIB というものもある.DIB は,「システムメモリ上のオフスクリーンサーフェイス」という描像がなされることが多いが,実際にほとんどの場合で CPU 処理がなされていると考えて良いだろう.結果,処理するピクセル数に比例したスループットを示すことが多い.CPU で描画命令を発行し,CPU で実際に塗りつぶす上で,どちらがより卓越するかといえば通常は塗りつぶしの方だからだ.

しかし,GPU によるアクセラレーションがほとんど期待できないにもかかわらず,DIB は衰退するどころか徐々に勢力圏を広げてきている.DIB 使いの筆頭は GDI+,そして GDI+ を使用するアプリケーションといえば Microsoft の Office 系アプリケーションとなる.先日の VSUG イベントで紹介した,Vista 風のブラー付き文字描画も,Theme API の出力先はアルファ値を持った DIB が期待されている*2.哀しいことに世の中 DIB ばっかりだ.この世界は Intel フラグ立ちまくりらしい.

ただし歴史的に Windows のデスクトップ画面は DDB ということになっているので(現象論的には,これはまさに DDB の定義に近い.デスクトップと互換するのが DDB だ),最終的にデスクトップに表示するには DIB から DDB への転送が必要となる.そういう意味で,DIB だけで Office が作られるわけではない.

また,Photoshop のような専門化向けソフト,とびでばいんのような 2D ゲームは,その根幹の処理は最初から独自のメモリバッファで行っている.ただし,各社独自アルゴリズムによる高速化処理で差別化を図っており,特定用途向けでは DIB よりも遙かに高い性能を示すだろう.もちろんこの場合も,最後に画面に表示するには DDB や DirectDraw の力を借りねばならない.

というわけで最初に戻る.性格真反対の双子に久しぶりに再会して,妹と思ったら実は姉の変わり果てた姿でした,みたいなのが WDDM 環境での DDB.ただし妹は妹のままなのがややこしい.これが最初の段落で言いたかったこと.

もちろん,DDB が常に DDB らしかったかというとそうではない,Virtual PC でエミュレートされているときや,Remote Desktop 経由のときは,当然 DDB のパフォーマンスは「それらしく」なかっただろう.WDDM 環境での DDB の豹変も,歴史をひもとけばこれがはじめてというわけではない.

例えば金子勇氏の NekoFlight には,GDI ベースのポリゴン描画モードがある(個人的には WinG モードよりも味があって好きだった).これを Virtual PC 2007 で動かすと見るに堪えない挙動を示すが,Remote Desktop 経由では比較的ましである.ちょうど今手元で Remote Desktop を 2 段階経由して実行しているところだが,それでも 45 FPS 出ているのは確認した(NekoFlight には Wait 設定があって,デフォルト設定では 70 FPS あたりでサチることに注意) .さて Virtual PC 2007 で悲惨なら,ソフトウェア処理されると考えられる Vista ではどうだろうか? 結果は恐れていたほど悪くなく,昨今の CPU であれば NekoFlight をソフトウェアポリゴンで描画しても十分 60 FPS 確保できると分かっただけだった.その意味は Virtual PC 2007 がむしろ残念ということになる.

一方で,元々 DIB または独自バッファで CPU 処理をしていたケースでは,環境の変化による差異がほとんどの場合 CPU 性能に帰結できる.どういう速度で動くかが CPU (とせいぜいメインメモリ)の速度だけで決まるため,非常に性能が予測しやすいのだ.「とびでばいんが(タイマー制御を解除すれば) Virtual PC 2007 環境でも 90 FPS で動作する」と聞いて,驚く人はまだ DIB (やソフトウェア描画)について理解が足りない.当時主流だった CPU で処理できるように作られているのだから,今の CPU で捌けないことはないだろう,と平然と言ってのけるぐらいでいい*3

さて,またまた話が脱線しすぎる前に元に戻そう.久しぶりに再会した DDB の性格がすっかり DIB になってしまっていた! ねーさん事件です! リバースカードオープン! 「1 秒間に呼べる BitBlt 数が一定から1 秒間に転送できるピクセル数が一定に!」 ,ここまでは OK としよう*4.問題は,その結果どうなるかだ.実は,これだけで「Windows Vista では○○ % も 2D 性能悪化」という記事が書き放題という話になる.○○ はお好みで好きな数字をどうぞ.ポイントはベンチマークスコアに Pixel Fill Rate を使うところにある.

例えば,ある Windows XP 環境では,16×16ピクセルの画像転送で,DDB to DDB と DIB to DIB が拮抗するとする(さっき測った).この場合,「Windows XP での,512 × 512 の画像転送速度を基準にします」と宣言すればよい.GDI のベンチマークを行うときは DIB か DDB かを明示しなくて良いという変な暗黙の了解があるらしいので(これに従わないのは善人か正直者である),ここは XP での DDB (512×512) to DDB を基準にとるとしよう.

そんなわけで「Windows Vista の 2D 描画は XP の 1000 倍遅い!?」を期待してわくわくしながら測ったみたら,残念,たったの 100 倍しか差がつかなかった.まあもともと桁の議論だし,「〜一定」はピクセル数が無限大に増加するときの漸近線の議論である.16×16ピクセルあたりだともう少しパラメータを増やす必要があるのかも知れない.荒っぽい議論だし 1 桁ぐらいの系統誤差はかわいいものだろう.100 倍で満足してもらえなければ,1024×1024 でも,2048×2048 でも好きなだけインフレを起こせばよいのだから.(それでもたぶんビクともしないぐらい,今の GPU は化け物だ)

例の記事について正直な感想を言えば,近年の Office では GDI 経由のハードウェアの利用効率がかなり下がってきていて,それをソフトウェア化してしまっても,実測スループット1/5 よく見たら1/3か 程度になるだけで済んでいる,のかな? といったところだ.単純にハードウェア処理をソフトウェア処理に置き換えたインパクトにしては,1/5 1/3 というのはどうもぬるすぎる.ソフトウェア描画の部分がかなりを占めていてそれが緩衝材になっているか,そもそもろくにハードウェアの性能を引き出せていなかったかどちらかだろう.もちろん,同じ環境を手元に用意して試してみないことには正確なところは何も言えない.しかし,2D CAD や先ほどのねらい澄ましたベンチマークだと,もっと悲惨なパフォーマンス・ダウンの数字を量産できるだろうに,この数字ばかりが引用されるのはちょっともったいない気がする.

ちなみに Office は 2007 になってアルファブレンディング(当然 DIB 経由の CPU 処理だろう)の使いっぷりにさらに拍車がかかっており,ますます Intel フラグが立ちまくりである.

では,WPF に移行すれば万事 OK かというと,そもそもパフォーマンス特性が従来の GDI とは異なるので,単純に移行というわけにもいかないだろう.同時攻略は難しい.それに,WPF 自体まだまだ瞬間的に起動という雰囲気でもないし.実際のところ,ブラウザ上のソフトウェアレンダリングで十分な領域は順当にブラウザに食われていくような気がする.ガジェットにしても,プログラマWPF 触らせるよりは,本職のデザイナさんに HTML 書いてもらう方が見栄えの平均値は高くなるだろう.

そもそも,正直 WPF は現物を見るまでもっと酷いと思っていた.だいたい .NET というだけで,「GC のせいでほにゃらら」とか「インライン展開がほにゃらら」とか言う人が必ず現れるのに,WPFRTM を迎えても GC とかそのあたりの現状を伝える記事が全然見あたらないというのはどういうことなのだろう? 要するに,みんな文章を書く暇はあってもベンチマークをとったり考察したりする暇はないということなんだろうか.

もし「WPF 遅いぜ!」な感じのベンチマークをとりたいという暇な方がいらっしゃるなら,WPF のパフォーマンスガイドで書かれていることの反対を選び続けることで比較的短時間のうちに実現できると思う.もうちょっとマニアックな人は,例えば WinHEC 2004 のときのうたい文句,「DirectX 10 世代(今で言うところの Direct3D9 Ex に該当)の PixelShader で 1 M Glyphs/sec 実現するよ(id:NyaRuRu:20060301#p2)」が,本当に WPF で実現できているか,なんてのは面白い検証ネタかもしれない.

あと,今更だけど GDI ベンチ書く人は,測っているのが DDB への処理なのか DIB への処理なのか,はたまた DDB to DDBDDB to DIB,DIB to DDB,DIB to DIB なのかぐらいは,明記して欲しいものだと思う*5
それから,ほとんど確実に CPU 律速になっているスコアについては,実際に CPU 律速かどうかも測定してあげないと,読者や利用者が「ビデオカードを買い換えればいいのかな?」といったあらぬ思いを抱きかねない.それはあんまりだと思う.

なんか最後は愚痴ばっかりになっちゃったけど,まあ暗黒雑学なんてそんなものということで.

勢いで書いちゃったので,何か事実誤認がございましたら,ご指摘のほどよろしくお願いします.

*1:そういえば Vista でユーザモードドライバ導入するからバッチ投入コスト下がるよみたいな話がありましたが,どうなったんでしょうかね?

*2:[http://www.codeproject.com/vista/VGGlassIntro.asp:title= Vista Goodies in C++: Using Glass in Your UI]

*3:とはいえ,大抵この手の発言はちゃんと動いているのを確認してから後付で理由述べているばかりなので,未来予言能力を期待してはいけない.Trick に出てくる悪徳霊能力者みたいなものだ

*4:とは言っても,元々ソフトウェア処理されていたらしき部分については振る舞いがややこしい,ちまたの GDI ベンチマークでは,DWM On の方が Off のときよりテキストレンダリング系のスコアは高いようである

*5:その点 id:LaMoo 氏の[http://lamoo.s53.xrea.com/develop/gdiplus/gdiplus_blt.html:title=これ]とかさすが