描画速度の測定

かなり古い記事なので、現状とはかなり異なる内容です。
ま、そんな時代もあったんだと思ってください・・・
さて、ゲームなどのプログラムを書いている時、
気になるのが、各APIの描画速度です。

DirectDrawを使えば、デバイスコンテキスト経由でも、
結構な速度が出るらしいのですが、
メニューバーを表示させたりするのが結構面倒なので、
自分は、DirectDrawをあまり多用しません。

そこで、DirectDrawを使わない時の各APIの描画速度を測定してみました。
  1. 画像は640×480のフルカラー画像。
    これを、32Bitの画像としてDIBSectionに読み込みました。
  2. 使用したPCはSharpのノートPC-FJ160M
  3. 言語は、VC++6
  4. アプリケーションウイザードでMFCを使用したSDIを構築。
  5. CDC::GetDC()で取得したデバイスコンテキストに対して描画。
なお、使った描画コマンドは
  • CDC::BitBlt()
  • CDC::StretchBlt()
  • ::SetDIBitsToDevice()
  • ::DrawDIBDraw()

です。

基本的に、
デバイスコンテキストの取得〜(HBITMAPからCBitmapの作成)〜描画〜デバイスコンテキストの開放
の手順にかかる時間を測定し、それを100回づつ繰り返し平均を算出しました。
その上で、それを5セット行い、更に平均を算出。都合、500回の平均です。

また、速度の測定は、CPUの内部タイマー(パフォーマンスタイマー)を使用しています。
今回使用した機種のCPUの動作クロックは550MHz。
ということは、このカウンターは1.8ps(=0.0018ms)毎に1増えますので十分かと。

結果です。
32 24 16
CDC::BitBlt 14.17 9.05 9.77
CDC:StretchBlt 14.20 9.08 10.20
::SetDIBitsToDevice 14.04 8.88 9.90
::DarwDibDraw 14.04 9.00 9.58

横軸の32,24,16は画面の色モードで、単位は、msです。

まず、API別の速度の比較ですが、
DrawDIBDrawや、SetDIBitsToDeviceの速度が
若干早いという傾向があるようですが、
一番差の大きい、16bppの時でさえ6%の差しかなく、
一番差の小さい、32bppの時に至っては1%の差です。
APIごとの速度さは、無いに等しいといってもいいでしょう。

さて、面白いのが、画面の色モード別の速度です。
用意したBitmapオブジェクトは32bpp(BitPerPixel)なのですが、
それをそのまま転送するだけですむはずの、
32bppのモードが一番遅いことが見て取れます。
それに比べると、画面モードが24bppと16bppの場合の差異は小さいです。

今回は、ゲームで使用するAPIという観点から、
実験をしていますので、その観点から結論を書くと、
DrawDibDrawを使うのが、一番ではないかと思われます。

というのも、今回は測定しなかった、
256色モードでフルカラー画像を描画すると、
自動的にディザをかけてくれるので、
こういう付加機能がある上、
他のAPIとほぼ同じか、それ以上の描画速度がある
DrawDibDrawに軍配が上がります。