指定した待ち時間を得るSleep()。ms(ミリ秒)単位で設定できるが、調べてみたら思いの外精度が悪い。元々いいとは思っていなかったのだけど、こんなに悪いのかと。
timeBeginPeriod()を使うと精度の指定ができるそうなので、それも確認するテストプログラムを書いてみた。
#define LOOP_NUM 10
#include <iostream>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "winmm.lib")
int main()
{
int i;
std::cout << "Seep 10, 20, 50, 100ms\n";
for (i = 0; i < LOOP_NUM; i++) {
DWORD start_10 = timeGetTime();
Sleep(10);
DWORD end_10 = GetTickCount();
DWORD start_20 = timeGetTime();
Sleep(20);
DWORD end_20 = GetTickCount();
DWORD start_50 = timeGetTime();
Sleep(50);
DWORD end_50 = GetTickCount();
DWORD start_100 = timeGetTime();
Sleep(100);
DWORD end_100 = GetTickCount();
printf("%3d %3d %3d %3d\n", (end_10 - start_10),
(end_20 - start_20), (end_50 - start_50), (end_100 - start_100));
}
std::cout << "\ntimeBeginPeriod()\n";
for (i = 0; i < LOOP_NUM; i++) {
timeBeginPeriod(1);
DWORD start_10 = timeGetTime();
Sleep(10);
DWORD end_10 = GetTickCount();
DWORD start_20 = timeGetTime();
Sleep(20);
DWORD end_20 = GetTickCount();
DWORD start_50 = timeGetTime();
Sleep(50);
DWORD end_50 = GetTickCount();
DWORD start_100 = timeGetTime();
Sleep(100);
DWORD end_100 = GetTickCount();
timeEndPeriod(1);
printf("%3d %3d %3d %3d\n", (end_10 - start_10),
(end_20 - start_20), (end_50 - start_50), (end_100 - start_100));
}
}
何の工夫もないベタ書き。10ms、20ms、50ms、100msSleepの前後で時刻を取得してその差分を表示。さらに、timeBeginPeriod()を使った場合も同様に計測・表示。これを10回繰り返す。
実行環境はWindows 10。
Seep 10, 20, 50, 100ms 15 31 57 108 14 31 63 139 32 25 55 118 28 36 60 110 25 32 62 109 16 33 61 112 24 14 54 118 47 37 68 115 19 34 65 114 21 36 68 115 timeBeginPeriod() 5 25 67 96 9 25 48 92 7 27 53 96 10 15 56 99 14 18 44 104 3 23 49 107 16 36 73 122 8 25 51 94 8 13 55 97 10 15 56 99
かなりバラバラ。こんなだから、実行する度にだいぶ違う。
Seep 10, 20, 50, 100ms 15 26 57 103 11 26 60 105 11 28 57 104 13 30 61 103 34 30 60 109 14 30 64 109 16 32 63 108 16 31 62 111 13 31 63 110 19 33 63 110 timeBeginPeriod() -1 19 45 103 2 22 48 90 6 10 52 95 7 12 54 96 11 16 42 102 1 22 48 92 7 12 39 97 9 12 100 137 22 21 47 102 21 29 49 92
Seep 10, 20, 50, 100ms 16 23 53 101 6 23 51 102 16 20 53 103 8 26 57 103 9 24 56 101 8 24 55 103 8 24 54 100 6 24 54 101 6 22 55 103 8 27 58 105 timeBeginPeriod() 8 12 53 96 0 20 46 105 3 23 49 92 6 11 51 92 7 11 53 96 9 24 48 91 6 10 52 96 9 13 39 98 14 17 43 102 1 21 47 89
Seep 10, 20, 50, 100ms 32 30 48 100 8 24 54 102 8 23 55 102 18 23 71 110 39 16 55 101 10 26 54 104 7 22 54 100 5 22 54 102 33 32 60 101 14 30 61 109 timeBeginPeriod() 11 15 41 99 14 19 45 102 1 20 46 99 15 20 46 104 3 23 49 93 7 13 39 98 13 18 43 117 12 42 49 113 12 23 49 100 0 20 46 89
Seep 10, 20, 50, 100ms 47 41 83 123 27 62 103 124 30 47 63 125 29 42 62 126 29 45 75 123 14 47 61 110 16 32 63 126 14 31 64 112 31 31 79 113 19 36 68 112 timeBeginPeriod() 21 25 52 111 26 31 57 116 15 34 60 104 19 22 64 116 15 35 61 105 20 24 50 110 24 29 56 114 14 34 61 104 19 23 65 107 22 27 53 112
timeBeginPeriod()を使わない場合は全体的に遅いという印象だけど、そうとも言えない場合もある。
timeBeginPeriod()を使うと遅さ(オーバヘッド時間みたいな感じ)は減るが、指定時間よりも短くなることもある。特に、時間が短いと影響(割合)が大きい。
バラツキはどっちもどっちだなぁ。
しかし、これほどまでに精度が悪いんじゃ、パドルエミュレータで打鍵ミスが出るのも仕方ないわな。エレキーの速度よりもパドルエミュレータの設定速度を多少早めに設定すると打鍵ミスが減るように感じたのもこのせいだな(timeBeginPeriod()は使っていないので、遅めの傾向になりがち)。
コメント