A Problem in Measuring Time by vsgGetTimer( )/ViSaGe
An alternative timer with finer
resolution
Function vsgGetTimer( ) returns a value with 100microsecond precision. But, when the program runs on a multi-task OS like Windows, switching between tasks may bring a trouble. To check this possibility, I wrote the following console application in Visual C++ 2008/CLR.
=====================================================
#include "stdafx.h"
#include <VSGV8.H>
using namespace System;
int main(array<System::String ^> ^args)
{
::vsgInit("");
::vsgResetTimer();
const int N = 100;
int
x[N];
int cnt = 0;
int t0, t1, ckt0, ckt1;
ckt0
= t0 = ::vsgGetTimer();
do {
t1
= ::vsgGetTimer();
if (t1 > t0){
x[cnt++]
= t1 - t0;
t0
= t1;
}
}
while (cnt < N);
ckt1
= t1;
for (int i = 0; i
< N; i++){
Console::Write(((x[i]*0.001).ToString()
+ "ms")->PadLeft(10));
if (i % 5 == 4) Console::WriteLine();
}
Console::WriteLine();
Console::WriteLine("Mean interval between increments = " +
((ckt1 - ckt0) * 0.001 / double(N)).ToString()
+ "ms");
Console::WriteLine();
Console::WriteLine("Press the Enter key.");
Console::ReadLine();
return 0;
}
========================================================
Run this code on ViSaGe, then you will get the following result (Figure 1).

Figure 1
Figure 1 shows that multi-tasking may introduce an error up to 15.625ms in measuring time.
I prepared a timer class with finer resolution than vsgGetTimer. This class is coded as follows:
==================== Header file finetimer.h =====================================
//
// A
fine resolution timer. Y.
Okamoto, 2010.03
//
#ifndef FINETIMER_CK
#define FINETIMER_CK
#include <Windows.h>
using namespace System;
namespace mytimer {
class MyTimer {
public:
LARGE_INTEGER
L_I;
bool ck;
double f;
double c;
MyTimer():
ck(false) {
if ( QueryPerformanceFrequency( &L_I ) ) {
ck
= true;
c
= Math::Pow(2.0, 32.0);
f
= L_I.LowPart + c * L_I.HighPart;
}
}
// In microsecond
unit
double time(){
if (ck) {
QueryPerformanceCounter(
&L_I );
double v = L_I.HighPart * c + L_I.LowPart;
return 1000000.0 * v / f;
}
else {
return 0.0;
}
}
// In millisecond
unit
int timems(){
return Math::Round(time() * 0.001);
}
};
}
#endif
=========================== End of header file finetimer.h ===============================================
You can check finetimer.h by the following console application in Visual C++2008/CLR
======================= A main source file finertimer.cpp to check finetimer.h ===============================
#include "stdafx.h"
#include "finetimer.h"
using namespace System;
using namespace mytimer;
int main(array<System::String ^> ^args)
{
const int N = 100;
int x[N];
int cnt = 0;
int t0, t1, ckt0, ckt1;
MyTimer
mt;
ckt0
= t0 = mt.timems();
do {
t1
= mt.timems();
if (t1 > t0){
x[cnt++]
= t1 - t0;
t0
= t1;
}
}
while (cnt < N);
ckt1
= t1;
for (int i = 0; i
< N; i++){
Console::Write((x[i].ToString()
+ "ms")->PadLeft(10));
if (i % 5 == 4) Console::WriteLine();
}
Console::WriteLine();
Console::WriteLine("Mean interval between increments = " +
((ckt1 - ckt0) / double(N)).ToString() + "ms");
Console::WriteLine();
Console::WriteLine("Press the Enter key.");
Console::ReadLine();
return 0;
============================= End of finertimer.cpp ======================================================
Run the program finertimer.cpp, you will get the following result.
============================================================
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
1ms 1ms 1ms 1ms 1ms
Mean interval between increments = 1ms
Press the Enter key.
===========================================================
Release version of the above program (.NET Framework 3.5) finertimer.exe
Packed files (Visual C++ 2008) finertimer.zip
More information about QueryPerformanceCounter function in Japanesec