読者です 読者をやめる 読者になる 読者になる

HSPのwaitとawaitの違い

waitとawaitなにが違うのという話をTLで見かけたので書いてみる。
ようするにwaitは常に指定秒数待つ、awaitは前のwaitから指定秒数待つということなのだが。
そうはいってもわかりにくいと思うのでまずはとりあえず検証プログラム。awaitとwaitを取り替えただけのプログラムでかかる時間を計測している。
ついでにしている処理の部分単体でもはかってみた。

#uselib "kernel32.dll"
#cfunc GetTickCount "GetTickCount"

//簡易ベンチマーク測定
//第一パラメータはベンチマーク名(省略可)
//第二パラメータは繰り返し回数(省略可)
//計測したい部分をSpeedMeasureStartとSpeedMeasureEndで囲む
#define SpeedMeasureStart(%1="No Name",%2=1) %tSpeedMeasure %i=%2 %c %i=GetTickCount() %c %i=GetTickCount() %c %s1 %c repeat %2
#define SpeedMeasureEnd %tSpeedMeasure loop %c logmes "<計測結果:"+str(%o)+">" %c logmes "合計:"+str(GetTickCount()-%o)+"[ms]" %c logmes "平均:"+str((GetTickCount()-%o)/%o)+"[ms]"



celload "enchuu.png",2

SpeedMeasureStart "Test1",10
repeat 100
	celput 2
loop
SpeedMeasureEnd


SpeedMeasureStart "Test2",10
repeat 100
	repeat 1000
		celput 2
	loop
	await 30
loop
SpeedMeasureEnd

SpeedMeasureStart "Test3",10
repeat 100
	repeat 1000
		celput 2
	loop
	wait 3
loop
SpeedMeasureEnd


走らせてみたら以下のような結果になった。

<計測結果:Test1>
合計:15[ms]
平均:1[ms]
<計測結果:Test2>
合計:30500[ms]
平均:3050[ms]
<計測結果:Test3>
合計:31391[ms]
平均:3139[ms]

ウェイトする部分で100回ループしていることを考慮して平均値を100で割ると
30.5[ms]
31.39[ms]
となって前者は小数点以下の制度はしょうがないので30msに近く、後者のほうは1ms遅い。1msが誤差の範囲かという問題だが、何回もループした結果の平均であるので優位な差であるといえると思う。
この差はどこにあるかといえば後者つまりwaitは描写処理に1ms費やしたあと30ms律儀に待っているのに対し、awaitは描写と待ち時間含めて30msになるようにしているのだ。
waitなしだと処理時間が大体1msなっていることからもわかる。
ようするに以下の図のようになっている。
f:id:ikaro1192:20120917205626p:plain
まとめるとwaitは常に指定秒数待つ、awaitは前のwaitから指定秒数待つということだ。
マラソンにたとえると次のように言えるかもしれない。
トラック一周ごとに休憩するとしてwaitの場合は10分休憩できる。
トラック一周ごとに休憩するとしてawaitの場合は走りはじめてから計り始め、一周したときに残り時間休憩できる。

したがってawaitはFPSを安定させるなどの時に有効だ。もちろん正確にするにはもっと工夫しないといけないのだが...