HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0825
riaHSP関数の実行時間について24未解決


ria

リンク

2009/8/25(Tue) 00:46:28|NO.27275

riaと申します。

HSPでゲームを創っている際に、立ち絵を表示するプログラムにてawait命令などは入れてないはずなのに、クリックして1秒以下くらい経ってから表示されてしまいます。
HSPの関数やHSPによるファイル読み出しは、読み出すときのタイムロスが他の言語よりも大きく発生するのでしょうか?

他に、
repeat〜loop
gmode gcopy ,gzoom if switch〜swend
を多用しているのがいけないのでしょうか。
特に、分岐命令を多用しているせいで、パイプライン処理が活躍しないからではないか・・・とも思っているのですが、実質原因が分かりません。



この記事に返信する


ORZ

リンク

2009/8/25(Tue) 01:41:44|NO.27276

表示毎にpicloadしているに1ジンバブエドル



ZxZ

リンク

2009/8/25(Tue) 07:54:50|NO.27277

buffer命令、gcopy命令について調べれば幸せになれるかもしれない



ria

リンク

2009/8/25(Tue) 08:46:37|NO.27279

>表示毎にpicloadしているに1ジンバブエドル
picloadを何度も使用するとちらつきが気になるので、一旦bufferに保存してからgcopyで画面表示するようにしています。

>buffer命令、gcopy命令について調べれば幸せになれるかもしれない
調べましたが、buffer命令は仮想画面に処理をする命令で、gcopy命令はそのbufferから仮想画面を切り出して表示する命令ですよね。
この2つの命令は元から使用しています。

もしかしたら、バッファのウィンドウIDを16くらい使用しているのが悪いのかもしれません。



SYAM

リンク

2009/8/25(Tue) 09:39:16|NO.27280

どんなことしてるのかわからないので原因までは突き止められませんが、
今日びのPCでゲームに使う程度の大きさの画像を picload で読んだところでそんなに目立つほどの時間がかかるとも考えにくいです。
よほどたくさん読むのなら別ですが立ち絵1枚なのですよね。

ところで
picload を使うとちらつく…ってことは、 redraw 0 で画面の更新を停止していないのではと思えるんですがどうでしょう?
redraw 0 で更新をとめていない場合、gcopy のような画面への描画が発生する命令は実行完了までにかかる時間がかなり増加します。
ちゃんと redraw 命令で画面更新の制御をしていますか?



SYAM

リンク

2009/8/25(Tue) 10:33:05|NO.27281

そもそものご質問に対する回答をいうなら、「そうです」。
基本的にHSPの命令や関数は、いろんなプログラム言語と比較すると遅い部類です。
特に命令ひとつひとつを実行すること自体も翻訳にかかる時間を要するので、実行ファイルがすでに翻訳済みの機械語であるような言語にはどうしても速度で劣ります。

が、立ち絵一枚表示するだけの処理でそんなに気になるような遅延が発生するほどの差でもないはずです。

とりあえず、何をしているのかがわからないことには、原因はわかりません。
結局、挙げられたもので原因として考えられるのはgcopy ,gzoomくらいのように見えますが、これらの命令で何を、どのくらい描いているのでしょう?repeatなどでループしてるならその回数も考慮して。

#ウインドウやバッファをたくさん作っても、スクリプトの実行スピードにさしたる影響は出ないでしょう。
#メモリを食い尽くすほどの大面積でもない限り。



あり

リンク

2009/8/25(Tue) 11:20:56|NO.27283

今の情報量では原因を特定しようがありませんが
怪しい部分の命令をコメントアウトして実行してみて
どの命令で処理が重くなるのか調べてみてはどうでしょう?
あと他に原因として考えられそうな事は・・・

・画面のクリアにclsを使っている ・ループ処理が重複している ・表示する画像の数が多いorサイズが大きい ・半透明処理を多用している ・OSがVista以降
とかもありますね。

どうしても原因が判らない場合には
最初からスクリプトを組み直すのも手だと思います。
スクリプトを再構築していくうちに今まで気づかなかった
問題点を発見できる事もあるかもしれませんし
より効率的なルーチンを組めるかもしれません。



KA

リンク

2009/8/25(Tue) 11:35:25|NO.27284

riaさん

>>HSPによるファイル読み出しは、タイムロスが他の言語よりも大きく・・・
>>picloadを・・・一旦bufferに保存してからgcopyで画面表示・・・
 → 毎回ファイルをbufferに保存し、gcopyで画面表示しているのでしょうか?

>>他に〜を多用しているのがいけないのでしょうか。
>>もしかしたら、バッファのウィンドウIDを16くらい・・・
 → 原因はともかく、聞く前にやってみるのが筋では?

この手の漠然とした質問は良く出てきますが、回答も漠然としてしまいます。
 1:遅い事が再現できる、最小限のスクリプトを載せる。
 2:使用した画像の種類・サイズを明記する。
これだけで、回答する側もやりやすくなります。



ria

リンク

2009/8/25(Tue) 14:30:30|NO.27291

>よほどたくさん読むのなら別ですが立ち絵1枚なのですよね。
いえ、立ち絵は各キャラ1枚ずつではなく、《【喜怒哀楽+その他数枚】×【10キャラ分】》あります。

>picload を使うとちらつく…ってことは、 redraw 0 で画面の更新を停止していないのではと思えるんですがどうでしょう?
えと、picloadを使うとちらつくというのは、一度picloadした後に、時間を空けずに再びpicloadする…というのを繰り返した場合でのことです。
今回はbuffer,gcopyとredrawを使っているのでちらつきませんでした。

>基本的にHSPの命令や関数は、いろんなプログラム言語と比較すると遅い部類です。
>特に命令ひとつひとつを実行すること自体も翻訳にかかる時間を要するので、実行ファイルがすでに翻訳済みの機械語であるような言語にはどうしても速度で劣ります。
HSPをネットで調べていた際に他の言語よりも遅くなるとは聞いていましたが、そのような理由だったのですね。

>#ウインドウやバッファをたくさん作っても、スクリプトの実行スピードにさしたる影響は出ないでしょう。
>#メモリを食い尽くすほどの大面積でもない限り。
うちのパソコンのメモリはまだMBなので、多分最近のPCよりはすぐに空きが尽きてしまいます。
ですがメモリ消費も考慮した上で反応が遅いので、多分違う理由だと思います。

>・画面のクリアにclsを使っている
>・ループ処理が重複している
>・表示する画像の数が多いorサイズが大きい
>・半透明処理を多用している
>・OSがVista以降
3番目の項目がもしかしたら関わっているかもしれません。
今回使っている立ち絵画像は、
・BMP形式
・1240×1600 ・フルカラー ・アルファブレンド対応
です。

> 1:遅い事が再現できる、最小限のスクリプトを載せる。
1に対して、以下にスクリプトを載せます。
最小限に抑えたつもりですが、遅くなる原因が分からないので少し長くなってしまいました。
#module
#deffunc picdis int kk,int xsize,int ysize,int mag,str Bfile0,str Bfile1,str Bfile2,str back,int xpos,int ypos,int blend /* kk,キャラ数 : xsize,画像Xサイズ : ysize,画像Yサイズ : mag,拡大縮小サイズ : Bfile,キャラ画像1 : Bfile1,キャラ画像2 : Bfile2,キャラ画像3 : back,背景画像 : xpos,キャラ位置 : ypos,キャラ位置 : blend,ブレンド率 */ //キャラ数の決定 repeat kk kcnt=cnt+17 buffer kcnt //キャラ画像の取得 switch cnt case 0 : picload Bfile0 : swbreak case 1 : picload Bfile1 : swbreak case 2 : picload Bfile2 : swend loop // buffer 16 : picload back : gsel 0 : gmode 0 buffer 13,xsize/mag*2,ysize/mag : gzoom xsize/mag*2,ysize/mag,17,0,0,xsize*2,ysize,1 repeat kk switch kk case 2 or 3 : switch mag case 1 or 2 : buffer 12, xsize*mag-3 ,ysize : pos xsize-1,-1: gcopy cnt+17,0,0,xsize/mag*mag,ysize : pos 0,-1 : gcopy cnt+17,xsize+1,0,xsize/mag*mag,ysize switch cnt case 1 : buffer 14,xsize/mag*mag-1,ysize : pos xsize-2,0 : gzoom -(xsize/mag*mag),ysize/mag,12,0,0,xsize*mag,ysize,1 : swbreak case 2 : buffer 15,xsize/mag*mag-1,ysize : gzoom xsize/mag*mag,ysize/mag,cnt+17,0,0,xsize*mag,ysize,1 : swend : swend : swbreak case 3 : if cnt=1 { buffer 14,xsize/mag*mag-1,ysize : pos xsize-200,0 : gzoom -(xsize/mag*mag),ysize/mag,12,0,0,xsize*mag,ysize,1 } : swbreak case 2 : buffer 12, xsize*2-3 ,ysize : pos xsize-1,-1: gcopy cnt+17,0,0,xsize/mag*2,ysize : pos 0,-1 : gcopy cnt+17,xsize+1,0,xsize/mag*2,ysize buffer 14, xsize*2 ,ysize : pos xsize*2,0 : gzoom -(xsize*2),1020,12,0,0,xsize*2,ysize,1 : swend loop gsel 0 pos 0,0 : redraw 0 : gcopy 16,0,0,640,480 //↓キャラ数分の画像表示 gmode 7,,,blend repeat kk if kk=1 { pos xpos,ypos : gcopy 13,0,0,xsize/mag,ysize } if kk=2 and mag>1 { pos xpos-(xpos/2)- 50,ypos : gcopy 14,0,0,xsize/mag,ysize : pos xpos+(xpos/2)+50,ypos : gcopy 13,0,0,xsize/mag,ysize } if kk=2 and mag=1 { pos xpos-(xpos/2)-140,ypos : gcopy 14,0,0,xsize/mag,ysize : pos xpos+(xpos/2)+100,ypos : gcopy 13,0,0,xsize/mag,ysize } loop : redraw 1 return #global
> 2:使用した画像の種類・サイズを明記する。
2に対して、先ほども載せましたがもう一度記載します。
・BMP形式
・1240×1600 ・フルカラー ・アルファブレンド対応



長くなってしまい、すみません。



ria

リンク

2009/8/25(Tue) 14:34:00|NO.27293

追記として、スクリプトはモジュール化して使用していたものを、少し改変して載せただけですのでご了承下さい。



あり

リンク

2009/8/25(Tue) 14:42:38|NO.27294

>・BMP形式
>・1240×1600
>・フルカラー
>・アルファブレンド対応
このサイズの画像を半透明コピーしようとすると
HSPにはかなり荷が重いように思います。
パソコンのスペックがそれなりでないと
最悪1秒に1枚表示できないなんて事もあるかもしれません。
小さい画像(640x480ぐらい)でも同じ速度しか出ないなら
スクリプトに問題があるのでしょうが・・・



SYAM

リンク

2009/8/25(Tue) 14:45:06|NO.27296

すいません、そんなにでっかいデータとは予想外でした…orz
そのサイズのBMPだと、1 枚で5MBをこえますね。それはさすがに重いです。
読み出しや合成処理、描画でそのくらい時間がかかっても、まったく不思議はないでしょう。



KA

リンク

2009/8/25(Tue) 15:44:06|NO.27298

>>パソコンのメモリはまだMBなので、多分最近のPCよりはすぐに空きが尽きてしまいます。

スワップの関係かも。



ria

リンク

2009/8/25(Tue) 18:11:56|NO.27300

>小さい画像(640x480ぐらい)でも同じ速度しか出ないならスクリプトに問題があるのでしょうが・・・
>
>そのサイズのBMPだと、1枚で5MBをこえますね。それはさすがに重いです。
画像を小さくして試してみたら、早くなりました。
が、なんというか・・・画像を小さくすると画質が悪くなってしまいました。
今回のゲーム制作で使用するイラストは他の人に時間を割いてもらって描いてもらったものなので、なるべくそのまま使いたいです。
なので、今の画像サイズでも早くすることは出来るのでしょうか。
それか、諦めて今の状態で制作を進行した方が良いのでしょうか。



足利超神

リンク

2009/8/25(Tue) 18:22:08|NO.27301

JPEGやPNGに圧縮するのは駄目なんでしょうか?



Ve

リンク

2009/8/25(Tue) 18:41:20|NO.27302

PNGに変換するのが一番綺麗でしょうかね。



あり

リンク

2009/8/26(Wed) 00:39:57|NO.27313

画像のコピー速度に関してはPCのスペックに依存するので
プログラムでの改善は難しいと思います。
DirectXを使えば最高速度自体は上がるでしょうが
必要スペックが上がりますし、要求水準に達していないハードでは
桁違いに速度が落ちてしまいます。

作っているソフトがCG集的な物であるなら
通常は640x480か800x600位に縮小してある画像を表示しておいて
拡大したい時だけ表示を切り替える等で対処しておく手もありますが
ゲームのようにリアルタイムで1240×1600サイズの画像を表示するのは
正直厳しいですね、エフェクトをかけるなら更に遅くなりますし。

そもそも作っているゲームの画面サイズは1240×1600ではないと思うので
ゲーム中は必要なサイズに縮小or切り取って使ってCGモード等では
全身表示させるとかではダメでしょうか?



ria

リンク

2009/8/26(Wed) 10:05:16|NO.27324

>JPEGやPNGに圧縮するのは駄目なんでしょうか?
>PNGに変換するのが一番綺麗でしょうかね。
BMP画像をPNGに変えてやってみましたが、容量的にはかなり軽くなりましたが速度は変わりませんでした。

>ゲーム中は必要なサイズに縮小or切り取って使ってCGモード等では
>全身表示させるとかではダメでしょうか?
一旦1240×1600の画像をバッファに保存してから、gzoomで別バッファに拡大縮小表示してからgcopyしています。
なので、画面に表示させるサイズは1240×1600ではなく、多分(620±100)×(650±100)くらいになっています。
補足として、ゲームウィンドウサイズは640×480です。

アルファブレンド画像なので横幅で結構とられるのが痛いですが、その方が綺麗に画像を表示できるのでその仕様でやっていました。



Ve

リンク

2009/8/26(Wed) 13:29:23|NO.27325

解決策としては

・コピーするサイズを小さくする
・コピーする回数を減らす
・パソコンのスペックをあげる
・DirectXを使う

無難にDirectXでしょうかね。



SYAM

リンク

2009/8/26(Wed) 13:46:02|NO.27326

>その方が綺麗に画像を表示できる

…のところが引っかかりますね。。
わざわざ画像をその場で加工するくらいなら、原寸のまま表示したほうがキレイなのは明らかだと思うのですが…。

すいません、どっか勘違いして見当はずれなこと言ってるかもしれませんが。
画面に表示する予定のサイズで画像データを用意しとけば いいのではないでしょうか?



ria

リンク

2009/8/26(Wed) 20:26:01|NO.27337

>・コピーするサイズを小さくする
>・コピーする回数を減らす
>・パソコンのスペックをあげる
>・DirectXを使う
1番目は、少し検討してみます。4番目については、DirectXについてはまだ勉強していないので、学んでみたいと思います。

>わざわざ画像をその場で加工するくらいなら、原寸のまま表示したほうがキレイなのは明らかだと思うのですが…。
>画面に表示する予定のサイズで画像データを用意しとけば いいのではないでしょうか?
確かにそうなのですが、何というか……。

今回創っているゲームの立ち絵に関連する使い道としては大まかに、
/////////
。腺庁屮僉璽箸任良充
 +α⇒主人公と仲が良くなれば画像をそのまま大きなサイズ(上半身のみ切り取り表示)で使用して『親近感』を現し、仲が普通または悪ければ縮小で『疎遠感』を現そうと思っています。
∪鐺パートにて、味方キャラ用に縮小表示
 +α⇒この方が、ゲームサイズ的に多少軽くなると思ったからです。
/////////
となっています。
もしも、『画面に表示する予定のサイズで画像データを用意』した場合、たとえPNGファイルで画像があったとしても、
。腺庁屮僉璽箸任硫菫(《100%=【喜怒哀楽+その他数枚】×【10キャラ分】》+《50%=【喜怒哀楽+その他数枚】×【10キャラ分】》)
∪鐺パートでの画像(10〜30%=【戦闘ver立ち絵1枚】×【10キャラ分】)
と、これだけあるので、現在のBMPファイル並みのサイズになってしまう気がします。



shinkun

リンク

2009/8/26(Wed) 20:55:54|NO.27339

話が戻りますが、ご容赦を。

すでに ORZ さん、KA さんが「毎回 picload してるんじゃないのか」と指摘されていらっしゃいます。私もそれに同感です。毎回の描画で ria さんの書かれた picdis を呼び出しているか、あるいはそれと同様の処理を行っているのではないでしょうか?

私のパソコンで picdis の処理時間を計測してみた所、およそ 800 [ms] 掛かっていました。これは ria さんのおっしゃる「クリックして1秒以下くらい経ってから表示されてしまいます」という事に一致していますよね。

試しに次のスクリプトを実行してみてください。こちらは、最初の 1 回だけ picload し、毎回の描画は gcopy だけを行うものです。これで速度が改善されるようでしたら、描画の度に picload → gcopy をやっている可能性が高いと思います。ちなみに私の方では 1 回の描画が 60[ms] 程度でした。

#uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" ; ウィンドウサイズを 1240 x 1600 に変更 screen 0, 1240, 1600, 0, 0, 0 ; 2480 x 1600 の画像をロード buffer 1 picload "img.bmp" ; 右半分は透明度指定用のグレースケール画像 gsel 0 gmode 7 *main redraw 0 pos 0, 0 s = timeGetTime() gcopy 1, 0, 0, 1240, 1600 e = timeGetTime() redraw 1 pos 0, 0 mes "" + (e-s) + "[ms]" wait 100 goto *main
img.bmp には、gmode 7 用に左半分を RGB(255,0,0)・右半分を RGB(255,255,255) で塗りつぶした 2480 x 1600 の画像を用いました。まぁ、大きさが合っていれば中身は何色でも関係ないです。

-----------------------------------------------------------------------------------
余談ですが、ria さん、switch 文中に

case 1 or 2: ...
と記述されていますね。これ、

case 3: ...
と書いた事と同じになってしまいます。
たぶん、意図したのとは異なる結果が生じているのではないかと。
以下のテストスクリプトを試してみてください。

repeat 10 switch cnt case 1 or 2 mes "" + cnt ; 1 と 2 が表示されれば良いが… swbreak swend loop



Ve

リンク

2009/8/26(Wed) 21:05:47|NO.27340

DirectX向きの処理ですね。標準命令だと表示に限界があります。

DirectXだと拡大しながらコピーしたり、反転・回転・αブレンド・半透明が可能です。


・使う画像とサイズをあらかじめ登録が可能
・↑上で登録した画像を番号で呼び出し描画できるようになります。
・決まった時間に描画するような処理になります。
・ハードウェアの能力を使うようになるので描画が早いです。
・DirectXを使う窓では標準命令の描画は一切使えない。
・標準命令から少し頭の切り替えが必要かも。

慣れれば難しくはないです。
描画では圧倒的なので使って見て下さい。

HSPでは、HSPDXFIXとHSP MULTIMEDIA( hmm.dll )が対応プラグインです。



shinkun

リンク

2009/8/27(Thu) 20:52:55|NO.27360

前回のスクリプト、これで速度を試した所で、あまり意味がない気がしてきました…。

ということで、1240 x 1600 サイズの画像 4 枚を転送するのに要する時間を計測するスクリプトを書きました。
たぶん、ADV でこれ以上の画像を同時に描画する事はあまりないと思うので、最大所要時間の目安になるのではないでしょうか?

なお、640 x 480 のウィンドウサイズだと言う事なので、スクリプト中の is_small を 1 に設定すると、そのサイズで動作するようにプログラムされています。

私のパソコンでは 1240 x 1600 時に 380 [ms] 程度、640 x 480 時に 30 [ms] 程度でした。
30 [ms] ならなんとか実用に耐えられるレベルではないでしょうか?

お暇がありましたら、ria さんもお試し下さい。


スクリプトはこちらから
http://cid-27bcd4da03c1a857.skydrive.live.com/browse.aspx/hsp%7C_bbs/NO.27275

画像提供:
語らいの一時オンライン 様
http://www.kataline.com/



というか

リンク

2009/8/30(Sun) 07:39:55|NO.27426

HSPだとDIBで持ってると思うので
 1240*1600*4(32bit)=約8MB となります。

読み込み(HDD→メモリ)、描画(メモリ→メモリ)それぞれ8MBの読み出し+書き込みをすることになるのですが
これは単にパソコンのスペックに依存するもので、C++とかでやってもほとんど変わらないです。
(HSPが遅いと言われるスクリプトの実行とは全く関係ないです。
 描画処理自体はCとかC++で記述されていると思いますが、おにたまさんのプログラムが遅いわけがありません:p)

あとPNGやJPEGにすると読み出しに更に時間が掛かります。
これらはファイルサイズを小さくするもので、picload後のサイズはbmpファイルと同じになります。


結論は、プリロードしておく、です。
シーン開始前に数枚分読み込みしておいてから、必要なときに描画
シーン終了時に解放、次のを読み込む、など。

DirectXなどでグラフィックカードを使う場合でも、そのサイズではファイルからの読み出しで止まってしまうと思われますので
立ち絵に空白などあれば、削って少しでも画像サイズを小さくすると良いと思います。

それでは。



ONION software Copyright 1997-2021(c) All rights reserved.