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


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0115
Buzzマイクロ秒単位の時刻取得について12解決


Buzz

リンク

2012/1/15(Sun) 10:43:57|NO.44289

HSPでgettime(7)にて、現在時刻をミリ秒単位で取得できますが、マイクロ秒単位での取得は、できないでしょうか?



この記事に返信する


HK2

リンク

2012/1/15(Sun) 11:56:13|NO.44291


s=gettime(7); repeat; t=gettime(7); if(s!=t){ c=cnt; break; } wait 0; loop; mes strf("開始時:%d\n終了時:%d\nデルタ:%d\n実行数:%d",s,t,t-s,c);

環境にもよりますが、システム時刻の分解能が1msもないので、gettime(7)より細かい時刻を取得しても意味はありません。

QueryPerformanceCounterとQueryPerformanceFrequencyを使ってみるのもいいかもしれませんが、
うまくいかなかったりするそうです。



HK2

リンク

2012/1/15(Sun) 11:57:35|NO.44292

「システム時刻の分解能が1msもないので、gettime(7)より細かい時刻を取得しても意味はありません。」
と書きましたが、意味がないのはそれより細かい値が正しいとは限らないということです。



MillkeyWeler

リンク

2012/1/16(Mon) 16:39:44|NO.44325

HSP-NEXT のホームページにマイクロ秒を計測できるソースが存在しますよー。

HSP-NEXT URL
http://hspnext.com/

の左側メニューの「HSPサンプル蔵」→「日付・時間操作系」に掲載されていますよー。



Buzz

リンク

2012/1/16(Mon) 23:04:41|NO.44351

MillkeyWelerさんのいったサイトの計測なんですが、QueryPerformanceCounter関数とQueryPerformanceFrequency関数
を使って計測するみたいなんですが、それがどうしても理解できなくて;
後、HK2さんが言ったことの理由も教えてほしいです。



check

リンク

2012/1/16(Mon) 23:44:24|NO.44355

現在の時刻をマイクロ秒単位で取得したいのか、
処理にかかる時間をマイクロ秒単位で取得したいのか、どちらだ?

そしてそのどちらの方法もない。
後者なら、以下のようにすればミリ秒単位で処理時間を計ることができる。
(それにしてもHSP-NEXTのサンプルは糞分かりづらいな。)

#include "kernel32.as" #define ALLOC_LARGE_INTEGER(%1) dim %1, 2 ALLOC_LARGE_INTEGER freq ALLOC_LARGE_INTEGER before ALLOC_LARGE_INTEGER after QueryPerformanceFrequency varptr(freq) if stat == 0 : dialog "ハードウェアが高分解能パフォーマンスカウンタをサポートしていません。", 1 : end QueryPerformanceCounter varptr(before) // 何らかの処理を入れる。(ここではwaitを入れているが必要ではない) wait 5 QueryPerformanceCounter varptr(after) timedif = (after - before) * 1000 / freq mes "処理にかかった時間は " + timedif + "msです。"

>HK2さんが言ったことの理由
別にそこまでの精度を必要としていないから。
仮に、現在の時刻をマイクロ秒単位で取得できたとしても、
どれだけ狂っているか分からないぞ。



たっくん

リンク

2012/1/17(Tue) 05:49:56|NO.44357

HSP-NEXTのはメモリ確保してない部分に書き込んでるので実行するのは危険。
check氏のは32bit分しか計算してないのでこれも問題ある。



check

リンク

2012/1/18(Wed) 00:39:37|NO.44374

HSPで64bit整数の計算を行う方法があったら教えてくれ。

結局HSPでQueryPeformanceなんちゃら関数を使うのは難しい。



aoi

リンク

2012/1/18(Wed) 01:16:50|NO.44376

checkのNO.44355スクリプトは ほとんどのPCで動かないので注意!!

HSP3ラウンジで QueryPerformanceFrequency を検索してみるべし。
この方法でやってて 今まで 動かないというのは聞いたことがない。



たっくん

リンク

2012/1/18(Wed) 01:42:22|NO.44377

longint.dllというプラグインで64ビット整数の計算ができるみたい。
プラグイン使わなくても少数に変換すればいける。

#include "kernel32.as" #define ctype I64TODBL(%1) double(strf("%%I64u",%1)) //64bit整数を少数に変換 ddim freq,1 ddim before,1 ddim after,1 QueryPerformanceFrequency varptr(freq) if stat == 0 : dialog "ハードウェアが高分解能パフォーマンスカウンタをサポートしていません。", 1 : end QueryPerformanceCounter varptr(before) // 何らかの処理を入れる。(ここではwaitを入れているが必要ではない) wait 500 QueryPerformanceCounter varptr(after) timedif = (I64TODBL(after) - I64TODBL(before)) / I64TODBL(freq) mes "処理にかかった時間は " + timedif + "秒です。"
あとはbeforeとafterのあいだでカウンターが一周したときの対処を入れとけば問題ないと思う。



check

リンク

2012/1/18(Wed) 02:02:49|NO.44378

aoi氏のレスに対してめんどくさいながらも物申すか。

>checkのNO.44355スクリプトは ほとんどのPCで動かない
手持ちのWindowsXP、メモリ512MBで動いたんで問題ないと判断した。

>HSP3ラウンジで QueryPerformanceFrequency を検索してみるべし。
したがそれらしい記事は見当たらなかった。

>この方法でやってて 今まで 動かないというのは聞いたことがない。
そして最後の謎の一文。
今までの発言と矛盾しているぞ。


たっくん氏のスクリプトでいいんじゃないかな。
wait 500は長すぎる気がするが。
結局HSPでは64bitの整数を扱えないので、64bitの浮動小数点数に変換して計算してやる必要があったりする。



たっくん

リンク

2012/1/18(Wed) 02:06:01|NO.44379

>HSP3ラウンジで QueryPerformanceFrequency を検索してみるべし。
http://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200707/07090030.txt
これの下から2番目のスクリプトのことかな。
なるほどx86のデノーマルを利用した方法で面白いけどこんなトリッキーなスクリプトは使うのやめたほうがいい。
この手法が通用するのはカウンタの値が一定値より低いことが条件でこんなのバグの温床になる。
今まで動かないというのは聞いたことがないとのことだがこれからもそうである保証などどこにもない。



HK2

リンク

2012/1/18(Wed) 20:46:41|NO.44389

端数を切り捨てて32bitでできるところまで頑張ってみました。
最後のµsを求める部分は表現領域の広い浮動小数点を使用しました。

本当は整数のみで完成させたかったです。
時間の間隔が2msを下回るのであれば、整数のみで計算できそうです。




#uselib "kernel32.dll" #func QueryPerformanceFrequency "QueryPerformanceFrequency" int #func QueryPerformanceCounter "QueryPerformanceCounter" int dim ll_frequency,2//周波数取得用。 dim ll_count1,2//カウンター用1(前) dim ll_count2,2//カウンター用2(後) dim i_frequency,1//32bit化周波数 dim i_count1,1//32bit化カウンター1 dim i_count2,1//32bit化カウンター2 dim i_adjust,1//調整値(ずらす量) dim i_deltatime,1//実行時間 //周波数取得部 mes "高分解能パフォーマンスカウンターの周波数を調べます。" QueryPerformanceFrequency varptr(ll_frequency) if(stat==0){ mes "高分解能パフォーマンスカウンターを利用できません。\n実行を停止します。" stop } //周波数に関するレポート部 if(ll_frequency(1)){ mes strf("周波数は16進表記で%8X%08X[Hz]です。",ll_frequency(1),ll_frequency(0)) }else{ mes strf("周波数は16進表記で%16X[Hz]です。\n10進数表記では%d[Hz]です。",ll_frequency(0),ll_frequency(0)) } if(ll_frequency(1)){ mes "周波数がHSPで扱える大きさを超えています。" }else:if(ll_frequency(0)&0xFF000000){ mes "周波数は扱いにくいほど高いです。" }else:if(ll_frequency(0)<1000000){ mes "周波数の逆数(周期)は1マイクロ秒を超えています。" } //32bitに調整(端数切捨て)部 if(ll_frequency(1)&0xFF000000){ i_adjust=5 }else:if(ll_frequency(1)&0x00FF0000){ i_adjust=4 }else:if(ll_frequency(1)&0x0000FF00){ i_adjust=3 }else:if(ll_frequency(1)&0x000000FF){ i_adjust=2 }else:if(ll_frequency(0)&0xFF000000){ i_adjust=1 }else{ i_adjust=0//本来は不要。移動量0ということを明示的にするために記述。 } memcpy i_frequency,ll_frequency,3,0,i_adjust *retry //計測部 QueryPerformanceCounter varptr(ll_count1) QueryPerformanceCounter varptr(ll_count2) //分析部 memcpy i_count1,ll_count1,3,0,i_adjust memcpy i_count2,ll_count2,3,0,i_adjust i_deltatime=i_count2-i_count1 if(i_deltatime<0){ mes "ループしました。\n測定をやり直します。" wait 100 goto *retry } i_deltatime=1000000.0*i_deltatime/i_frequency mes strf("QueryPerformanceCounter自体の処理時間は%fマイクロ秒です。",i_deltatime); wait 500 mes "再度計測します。" goto *retry



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