Hiragi(GKUTH)の日常
理系大学生の日記

円の描画はクソ遅い。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

円の描画はクソ遅い。

投稿記事 by Hiragi(GKUTH) » 10年前

なんか考査期間になってから日記の投稿速度が加速度的に早くなってきている気がします(勉強しろ




と、今回私が勉強そっちのけでやったのは大量のオブジェクトを描画するというモノです。折角一昨日にモジュール化という便利な物
を習得したので、それを使って同じオブジェクトを大量に描画してみよう、ということでよくベンチマークであるような図形を大量に描画させてみました。
で、


最初はオブジェクトの要素数がオブジェクトの生成数を下回り、フルスクリーンモードで起動した時、画面が鮮やかなピンク色になって電源が落ちました。
なんとまぁ自分で作るプログラムはアブナイものかと、その辺をちゃんと考慮して組み直し、適当に重力を付加させて、ぴょんぴょん跳ねるような動作をする
図形を1つのモジュールとして作りました。DXライブラリを使用していますので、図形描画系関数は

DrawLine,DrawPixel,DrawBox,DrawCircle,


とこの4つを基本として描画させてみました。詳細な個数を見たかったのでDrawFormatStringを用いてカウンタの
描画を行おうとしたのですが、何故かその関数を使用すると1500個ほど描画したところでいきなりCPUがフルロードされるようになって使い物にならなかったので10000個毎に
だけ、描画させるようにしました。故に計測値は目分量です。マルチスレッドには対応していないので、4Coreな私のCPUの場合25% +-5%ぐらいしか使用してくれなかったようです。



計測条件:画面サイズはVGA(640x480)にし、フレームレートはココのサイト様の特定のFPSで動作させる、のC言語Verを用いFPSの測定、制御を行いました。
初期FPSは60(=リフレッシュレート)にし、FPSが30を切った時点での描画個数をDrawCircleを除き100000単位での表示を行い、途中だった時は目分量で1/10まで計測する。
DrawCircleに関しては超遅かったので10000単位での表示を行い、それ以後は他のモノと同様に計測しました。



環境
OS:Windows 8.1
CPU:i5-4670 3.4GHz
Mem:16G
GPU:GTX760 OC(最高1115MHz)
コンパイラ:VC++ 2013 for Desktop
ライブラリ:DxLibrary

そして、

DrawPixel:300000個
DrawBox:300000個
DrawLine:340000個
DrawCircle:28000個

という感じの結果になりました。DrawCircleは1/10ほどの速度しかでていません。
加えてこれらのテストでGPUへの負荷は殆ど認められませんでした(2-5%程度)(ただしDrawFormatStringを描画する瞬間だけ95%に跳ね上がる)
ただ描画した個数に比例してCPUへの負荷がかかっているように見えました。

円の描画遅すぎだろ...と言った感じでした。終わり。



と、まったぁ! 画像の描画がまだだぞ! というわけで適当に画像(32x32のwindows標準bmp画像)を用意し、それを用いて描画させてみました

DrawGraphを用いました
DrawGraph:310000個

はい、もうGPUのベンチではありません、ただのCPUベンチになってしまいました。
DXライブラリでの円の描画はCPUを用いているようですね。(DxLibのソースを見たことがないので詳しいことはわかりませんが)

弾幕ゲーではいかに高速化をするか、考えなくてはいけなくなるんでしょうねぇ...



さて、明日はコミュニティ英語Ia 世界史 数学A の三教科の考査だし勉強頑張るぞー(遅い

プログラミング楽しすぎて楽しすぎて...(すっとぼけ

ソースコードは前回の日記のを使いまわしています。(マリオのは無効化してる)

► スポイラーを表示
頭の悪さが一瞬でわかってしまうコード...なんとかしたい。

YuO
記事: 947
登録日時: 14年前

Re: 円の描画はクソ遅い。

投稿記事 by YuO » 10年前

四角形は直線四本で済みますが,円は計算することが色々多いですからね……。
基本的は(r * cos Θ + x0, y * sin Θ + y0)の集合をΘ順に並べて直線で繋げば円になります。
実際にはもっと効率のよい描き方をしているとは思いますが,直線や四角形に比べて円の効率は常に落ちるでしょう。

画像の転送は,単純にコピー先の位置からコピー元の位置を計算して色を決定していくだけなので,円よりもよっぽど速いはずです。
拡大・縮小がなく,形式も揃っていれば単純にメモリのコピーなので速度は出しやすいですし。

taketoshi
記事: 222
登録日時: 14年前

Re: 円の描画はクソ遅い。

投稿記事 by taketoshi » 10年前

昔のHD-Benchってソフトウェアを想いだしました。
DOS-Vマガジンとかでベンチマークソフトの王道で、同様の処理をしておりました。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

Re: 円の描画はクソ遅い。

投稿記事 by Hiragi(GKUTH) » 10年前

YuO さんが書きました:四角形は直線四本で済みますが,円は計算することが色々多いですからね……。
基本的は(r * cos Θ + x0, y * sin Θ + y0)の集合をΘ順に並べて直線で繋げば円になります。
実際にはもっと効率のよい描き方をしているとは思いますが,直線や四角形に比べて円の効率は常に落ちるでしょう。

画像の転送は,単純にコピー先の位置からコピー元の位置を計算して色を決定していくだけなので,円よりもよっぽど速いはずです。
拡大・縮小がなく,形式も揃っていれば単純にメモリのコピーなので速度は出しやすいですし。

GPU積んであるのでVRAM -> GPUへのコピーでしょうし早いんでしょうね。
円の描画方法とかはまだ高校生(言い訳)ですしsin cos tanが最近始まった位な感じなので、まだ良くわかりませんが、
やっぱり曲線とか、円とか、ニンゲンから見て美しいような図形とかは難しいんでしょうねぇ フラクタルを思い出します。
GPUのベンチとかだと超高解像度画像(2048x2048位?)を縮小して描画しまくれば重くなるんでしょうかねぇ

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

Re: 円の描画はクソ遅い。

投稿記事 by Hiragi(GKUTH) » 10年前

taketoshi さんが書きました:昔のHD-Benchってソフトウェアを想いだしました。
DOS-Vマガジンとかでベンチマークソフトの王道で、同様の処理をしておりました。


折角なので回してみました。
画像

実行中にマウスポインタが動かなくなるほど負荷がかかって怖かった...なんか色々メッセージ処理が出来てなさそうな感じでした。
動作もかなり不安定だったので冷や汗をかきました。

ほぼすべてのスコアが表示範囲を超えていて普通に表示範囲内でした。見るのが不可能な感じです。
しかしなぜかGPUに関してはむしろ大幅なスコアダウン、なんか色々ヤバイ感じの動作してたのでそれが原因でしょう。

クリップボードに貼れるようなので貼ってみました。



★ ★ ★ HDBENCH Ver 3.40 beta 6 (C)EP82改/かず ★ ★ ★
M/B Name
Processor 3400.00MHz[GenuineIntel family 6 model C step 3]
Processor 3400.00MHz[GenuineIntel family 6 model C step 3]
Processor 3400.00MHz[GenuineIntel family 6 model C step 3]
Processor 3400.00MHz[GenuineIntel family 6 model C step 3]
VideoCard NVIDIA GeForce GTX 760
Resolution 1920x1080 (32Bit color)
Memory 4194,303 KByte
OS Windows NT 6.2 (Build: 9200)
Date 2014/09/23 12:59

ALL Integer Float MemoryR MemoryW MemoryRW DirectDraw
349098 855561 182447 687256 655512 1255526 31

Rectangle Text Ellipse BitBlt Read Write RRead RWrite Drive
65400 115800 110840 46804 479251 311719 304309 176856 C:\100MB

yellowman
記事: 0
登録日時: 10年前

Re: 円の描画はクソ遅い。

投稿記事 by yellowman » 10年前

なんか色々ヤバイ感じの動作してたのでそれが原因でしょう。



________________
fut 15 coins

アバター
usao
記事: 1889
登録日時: 12年前

Re: 円の描画はクソ遅い。

投稿記事 by usao » 10年前

線とか円とかの描画ではブレゼンハムのアルゴリズムが有名ですね.
円の描画とか自前で実装したくなったことは無いのでまともに最終的な演算内容まで把握してはいませんが.

しかし線と比較して円がそんなにも遅くなるものなのかなぁ? という印象.
単純に描画すべき画素数が 円が線の10倍くらいだった…とかいうことは無いのでしょうか?

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 14年前
住所: 大阪府
連絡を取る:

Re: 円の描画はクソ遅い。

投稿記事 by Hiragi(GKUTH) » 10年前

>>usaoさん
うーむ、あまり関係なさ気な感じですねぇ、たった今検証した結果、
DrawBoxを用いての描画を各辺が50で描画させました。
画素数はDrawPixelの2500倍。なのに結果はあまり変わらず。
DrawCircleの時も座標を指定して、半径rを整数値の25を渡しているので、実際の描画画素数はむしろ円のほうが少ない気がしますね。
パラメータの中にぬりつぶすかどうかのモノが有りましたがどちらを選んでもほぼ違いは見受けられませんでした。

で、半径rの値によっての負荷の変化は見受けられました。

DrawCircleのrは0でも1ドット描画されたあたり、もしかしたら内部で+1でもされてるのかもしれませんけどそうしたら乗数での効率化とかは上手く言ってないかもしれない。
r = 64 : 12000
r = 32 : 22000(+10000)
r = 16 : 28000(+6000)
r = 08 : 38000(+10000)
r = 04 : 45000(+7000)
r = 02 : 52000(+7000)
r = 01 : 60000(+8000)
r = 00 : 60000(+0)

比例に近いかもしれない。CPUの動作周波数を固定していないためそもそもの演算速度が一定でないし、と言うか目視での確認なのでそんなもんでしょう。

このぐらいなら画像を用意しておくであるとか、予め設定しておいた2次配列に従ってDrawPixelを並べるであるとか、そのほうがよっぽど早そうですねぇ、
描画するたびに計算し直すというのは時間がかかるみたいです。

なおこの計測で書き換えているのはDrawをする関数内だけですので座標の計算などは一切手を加えていません。