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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
1020
mammalwait が不安定16解決


mammal

リンク

2015/10/20(Tue) 20:40:27|NO.72398

報告か質問か迷いましたが、失礼します
wait 1をはさんでループ処理をさせている部分のあるプログラムを組んだのですが、時折waitが暴走してしまいます

デスクトップ常駐型アプリということで、時間の正確さよりも低負荷をとろうとawait 10ではなくwait 1をつかいました
処理は滞りなく行われ、負荷もほとんどありませんでした
ところが何回か実行してみると1/10くらいの確率でCPUをガッツリ使用しているのです(25%前後ほど)

少しばかり検索してみると、以下のログがありました
http://hsp.tv/play/pforum.php?mode=pastwch&num=54114
どうやら3.3時代からあったようですが、3.4でも治っていないのでしょうか



この記事に返信する


スペース

リンク

2015/10/20(Tue) 20:54:07|NO.72399

私が知らないだけかもしれませんがwaitよりawaitのほうが重い、という話は聞いたことが無いですね。
少なくともawait 33(30FPS)程度なら、実用的な範囲内ではないでしょうか?



mammal

リンク

2015/10/20(Tue) 21:17:29|NO.72400

>スペースさん

リファレンスのwait項目でこうありましたので

await命令を使うとwait命令よりも高精度で細かいウエイトが可能ですが、wait命令よりもCPUのタスクを消費します。 リアルタイムに画像を書き換えるなどの処理でなければ、 wait命令を使用した方がCPU(Windows)の負担が軽くなります。 常にデスクトップに配置するようなアクセサリにはwait命令を、ゲームアプリケーションなどにはawait命令を使うといった使い分けをするといいでしょう。

実際うまくいくと自分の環境では、ループに画像バッファコピー処理込みで使用率ほぼ1%、await 10になると5%ほどです
バッテリ監視・警告もさせたいのですこしでも余計な処理は控えておきたいのです
まぁ最近のCPUでその程度気にするなと言われればそれまでなのですが……



スペース

リンク

2015/10/20(Tue) 21:48:22|NO.72403

まさかリファレンスに書いていたとは!
教えて頂きありがとうございました。

waitを使わない方法ならウィンドウメッセージを使ってみてはどうでしょう?
http://blog.goo.ne.jp/hiro239415/e/c38d873d6a2749286791363f686c478d
(CPU使用率等は確認していません)



暇人

リンク

2015/10/20(Tue) 23:23:55|NO.72406

更新履歴には無いけど

>2015/02/18 3.5 beta1
> 新規プリプロセッサ命令、#bootoptを追加
> #bootopt命令によるタイマー精度の設定変更に対応
この時に直ってる感じ

3.5 beta2で100回ぐらい試しても異常はなかった



zakki

リンク

2015/10/21(Wed) 00:17:39|NO.72411

リンク先のスクリプトの改変版です。

GetTickCount() と timeGetTime() はどちらもWindows が起動してから経過した時間を返しますが、プロセスを起動するごとにそれぞれのAPIが返す時間に固有のズレができるようです。
でawaitでは一貫してtimeGetTime()で取得した時間を使うので問題ないのですが、waitではGetTickCount()で取得した時間を基準としてtimeGetTime()で取得した時間まで待つので、timeGetTime()の方が充分大きい値(恐らく5ms以上)を返す場合、waitが実質機能しません。
3.5系では若干事情が変わりそうですが、少なくとも3.4ではawaitでwaitで指定したかったのより若干長めの時間待つのがいいんじゃないかと


#uselib "kernel32.dll" #cfunc GetTickCount "GetTickCount" #uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" SizeX = 500 : SizeY = 40 screen 0, SizeX, SizeY, 1, 0, 0;( ginfo_dispx - SizeX ) / 2, ( ginfo_dispy - SizeY ) / 2 PreTime = gettime(6) repeat repeat 50 wait 1 //描画 redraw 0 color 255, 255, 255 : boxf 0, 0, 30, 20 : color pos 0, 0 : mes Fps redraw 1 gosub *GetFps loop t1 = GetTickCount() t2 = timeGetTime() title "" + (t2 - t1) loop *GetFps FpsCnt ++ : PostTime = gettime(6) if PostTime ! PreTime : Fps = FpsCnt : FpsCnt = 0 : PreTime = gettime(6) return



Noap

リンク

2015/10/21(Wed) 00:33:19|NO.72412

waitでそのような不具合には一度も遭遇したことがないのでわかりませんが
スペースさん、mammalさんの言う通りawaitとwaitは機能が違います。

HSPCTX構造体を見れば多分分かりますが(hspctx(62)とhspctx(63))awaitは前回の時間からawaitを呼ぶまでにかかった処理の時間を待ち時間の考慮に入れるのに対し、
waitは処理してからその時間待つというようになっています。ですのでmammalさんの引用の通りヘルプに書いてある通りゲームにはawaitが向いています。


スレッドの話とは違いますが前スペースさんがわざわざわたしの質問のために書いてくださった共有メモリのサンプルはとてもあのスレッドの後よく見ましたがいったいどういうことをしているのかがとてもわかりやすかったです。ありがとうございます。ずっと忘れていてすみません。
それであの時はそのことで頭がいっぱいですっかり頭の中から消えていてそれからずっと書くのを忘れていましたが、ビットマップのオブジェクトは通常のVirtualMallocなどで確保したメモリとは別物の扱いなのでできません。
スペースさんならばWindowsプログラミングにわたしよりとても長けていると思うので多分余計なお世話ではあると思いますが伝えておきます。

何か間違えていればごめんなさい。



Noap

リンク

2015/10/21(Wed) 01:40:26|NO.72413

わたしが書いている間にzakkiさんが私の説明よりサンプルスクリプトもつけてとても分かりやすい説明になっているのでzakkiさんの説明のほうが分かりやすいです。



toto

リンク

2015/10/21(Wed) 02:50:46|NO.72415

wait 1でCPU使用率が上がることについて、だいぶ前に以下のレスの後半で原因はGetTickCounが
混在していることが指摘されてますがまだ直っていないようです。
http://hsp.tv/play/pforum.php?mode=all&num=59353#59506
HSP3.5β2で一見直っているように見えるのはHSPのタイマー精度の仕様変更でスクリプトの内容に
よってはタイマー精度が上がらないようになっているので、その状態だとGetTickCounとtimeGetTimeの
精度が同じになるからです。
タイマー精度を上げてやればまだ問題が残っているのが確認できます。
以下のスクリプトを何回か実行すればCPUの使用率が上がります。

await 0//スクリプト中にawaitがあるとタイマー精度が上がる。ちなみにbootoptは現在機能していない。 repeat wait 1 loop



Noap

リンク

2015/10/21(Wed) 03:02:13|NO.72416

原因は理解できたような理解できなかったような感じです
パソコンは難しいです



窓月らら

リンク

2015/10/21(Wed) 07:41:19|NO.72418

Windowsのタイマー精度は言語とは関係なしにいつも問題。



スペース

リンク

2015/10/21(Wed) 10:33:56|NO.72420

>>Noapさん
awaitは前回の仕様から一定時間待つというのは知っていましたが、
処理が思いとはmammalさんの投稿で知りました(´・ω・`)

共有メモリの事ですが、ご指摘ありがとうございます。



暇人

リンク

2015/10/21(Wed) 18:51:08|NO.72423

あぁ、まだ直った訳じゃないのか・・・



mammal

リンク

2015/10/21(Wed) 21:42:03|NO.72424

みなさんありがとうございます
やはり未だに解決できていない問題のようですね
スペースさん代替案ありがとうございます
しかしまだAPI関係の使い方はよくわかってないので、それまではzakkiさんの「awaitによる遅延」をとってみます

「waitのバグは未だ改善されていない」が結論ということで一応解決チェックつけておきます
できれば修正をしてもらいたいものですが……



toto

リンク

2015/10/22(Thu) 05:45:07|NO.72428

>awaitは前回の仕様から一定時間待つというのは知っていましたが、
>処理が思いとはmammalさんの投稿で知りました(´・ω・`)
waitよりawaitのほうが処理が重いということはないと思いますが。
かなり昔のバージョンのHSPではそうでしたが現在では変わらないはず。
そのリファレンスは古い内容のままなんじゃないかと。
>ループに画像バッファコピー処理込みで使用率ほぼ1%、await 10になると5%ほどです
単にawaitでは画像処理時間の分待機時間が短くなるからだけだと思います。



toto

リンク

2015/10/22(Thu) 06:02:43|NO.72429

↑の追記
HSP3.5以降ではwaitではなくawaitつかうとタイマー精度が上がるのでバッテリーの減りが早くなったりする場合があるそうな。



Noap

リンク

2015/10/23(Fri) 19:34:40|NO.72448

HSPCTXの数値をawaitで使っていることは知っていましたがwaitでも使っていることは知りませんでした
awaitの数値はあるのにどうしてwaitの数値はないのかと不思議には思っていましたがあまり気にしたことはありませんでした
精度の違うタイマーをまぜてちかっているとは思いつきませんでした
totoさんzakkiさん、勉強になりました。

以下waitでも使っていることの確認スクリプト
waitでは5秒たつ前にキーを押した場合にはhspctx(63)の数値は変化しないのに対し、5秒たった場合にはhspctx(62)と同じ数値が代入されます。(これが知ったこと)
awaitでは開始時のタイマー(timeGetTime)の数値がhspctx(63)に、hspctx(62)には開始時のタイマー(timeGetTime)の数値にawaitで指定した数値を足した数字が代入されます。(これが知っていたこと)


#uselib "winmm.dll" #func timeGetTime "timeGetTime" #uselib "kernel32.dll" #func GetTickCount "GetTickCount" cls mref hspctx,68 dim timer,2 GetTickCount timer(1)=stat timeGetTime timer(0)=stat mes "タイマー(timeGetTime)="+timer(0)+"\nタイマー(GetTickCount)="+timer(1)+"\n5秒に間に何かキーを押してください\n(実際の命令とはタイマー取得と表示のぶん誤差はあります)" //wait 0 onkey *a //await 5000 wait 500 *a mes "wait(await)の数値="+hspctx.60 mes "タイマー(終了時)="+hspctx.62+" timeGetTimeとの差="+(hspctx.62-timer.0)+" GetTickCountとの差="+(hspctx.62-timer.1) mes "タイマー(開始時)(await)="+hspctx.63+" timeGetTimeとの差="+(hspctx.63-timer.0)+" GetTickCountとの差="+(hspctx.63-timer.1)



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