Page 3 of 3
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Sun Oct 08, 2017 5:44 pm
by wriedmann
Hi Karl-Heinz,
I'm using this function only for performance measurements, because it seemed more precise than other funtions.
Wolfgang
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Sun Oct 08, 2017 6:39 pm
by Karl-Heinz
Hi Wolfgang,
Honestly: Even if it would be for performance measurements only, i would never ever use this GetTickCountLow() nonsense !
regards
Karl-Heinz
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Mon Oct 09, 2017 3:23 am
by wriedmann
Hi Karl-Heinz,
yes, now that I know its problems, I have replaced this function with the one from the Windows API.
Wolfgang
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Mon Oct 09, 2017 8:17 am
by ic2
But we have to admit that the times of the desktop computers as the main IT instrument have finished....So we can be glad if Microsoft modernizes that world and that most of our program code is still working.
Hello Arne,
That depends. It's true that people do a lot of lookups and message reading & sending with mobile phones. Of course Pc's are much easier to use for that, with proper keyboards and easier access to stored data etc, but apparently many people prefer their phone for that because they always have it switched on and near them, also outside home. But none of the major functions most of us are programming for can be done without Pc's. In the past few years I've written only one smartphone + 1 tablet app for clients who paid me for that. Some other apps are in the Microsoft Store but I won't make (real) money with it. So I am not sure if Microsoft has done much here which improved the world (quite some modernizing in technology hasn't improved anything or even did the reverse).
Hmmm, we're getting a bit off topic so we should probably move it to chit-chat...
Dick
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Thu Dec 06, 2018 10:49 am
by Otto
To whom this may concern:
If you want to use GetTickCount64() in VO (thanks to Robert):
Code: Select all
function T() as void strict
local mystruct is myint64
local f as float
mystruct.r8 := GetTickCount64()
?
// in a float you could loose data, because e.g. float is signed.
f := mystruct.ul.LowPart * 1.0 + mystruct.ul.HighPart * 0xFFFFFFFFU
? Str(f,-1,0)
// the raw data, without loss.
? mystruct.ul.HighPart , mystruct.ul.LowPart
return
function Start()
? "Hello World"
do while true
T()
// the pause is not exact, so the interval is not exact either
Sleep(100)
end
WAIT
return nil
_dll function GetTickCount64() as real8 pascal:Kernel32.GetTickCount64
// returns 8 bytes
// _winULARGE_INTEGER
union myint64
member r8 as real8
member ul is _winULARGE_INTEGER
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Thu Dec 06, 2018 11:18 am
by ic2
Hello Otto,
Thanks for this follow up message. However, I do not understand what I should do to use it.
We now have:
dwTicks := GetTickCountLow()
This is supposed to :
Get the number of 1/10000 seconds that have elapsed since Windows was started.
The sample program is a loop with a pause function.
How is this supposed to give that number of 1/10000 seconds?
Dick
VO 2.8: GetTickCountLow() does not seem to work correctly anymore
Posted: Thu Dec 06, 2018 12:00 pm
by Otto
I used the loop to test what the effect on memory was and check what the interval between the calls is.
You can use the float interpretation of the memory block. As described in the formula.
you can use the upper and lower part of the numbers as dwords and work from there.
GetTickCountLow stops after 4 days (because than you'll run out off the counters range.
GetTickCount64 has more memory, and you'll probably won't live long enough to see running that out of range.
As noted by Microsoft: GetTickCount64 is in milliseconds, so 1/1000, and has resolution issues.
GetTickCount64 on Microsoft
GetTickCountLow() does have those as well. To bad we don't have the code of the runtime so we don't know what's in that concoction.
There are other options.
Personally I used the QueryPerformanceCounter and QueryPerformanceFrequency to get a higher resolution like in the following example of a stopwatch.
Calculations however cost time as well... so if you get a lot of data, converting the raw QueryPerformanceCounter data to fractions of seconds could be better done at the end of the process, when you are ready to report.
Code: Select all
class StopWatch3
protect StartMoment_high as longint
protect StartMoment_Low as dword
protect Frequency as dword
declare method Start
declare method Stop
method Init() class StopWatch3
// frequency added to make the recorded time comparable independend of the hardware etc.
local frequency_high := GetQueryPerformanceFrequencyHigh() as longint
self:Frequency := GetQueryPerformanceFrequencyLow()
if frequency_high != 0
_DebOut32(String2Psz("GetQueryPerformanceFrequencyHigh() != 0! (" + NTrim(frequency_high) + ")"))
endif
return self
method Start() as void strict class StopWatch3
local start_high as longint
local start_low as dword
GetQueryPerformanceCounter(@start_high,@start_low)
self:StartMoment_high := start_high
self:StartMoment_Low := start_low
return
method Stop() as real8 strict class StopWatch3
//#l get the elapsed time upto now since the Start.
local stop_high as longint
local stop_low as dword
local delta as dword
GetQueryPerformanceCounter(@stop_high,@stop_low)
delta := hldif(stop_high,stop_low,self:StartMoment_high,self:StartMoment_Low)
return real8(delta)/Frequency
function GetQueryPerformanceFrequencyHigh() as longint strict
local lpFreqebcy is _WINLARGE_INTEGER
QueryPerformanceFrequency(@lpFreqebcy)
return lpFreqebcy.u.HighPart
function GetQueryPerformanceCounter(highPart ref longint , LowPart ref dword) as void strict
local qpcValue is _WINLARGE_INTEGER
QueryPerformanceCounter(@qpcValue)
HighPart := qpcValue.u.HighPart
LowPart := qpcValue.u.LowPart
return
function hldif(ah as longint,al as dword, bh as longint, bl as dword ) as dword strict
//#l calculate a-b
//#l assume a>b
//#l assume that the difference is lower than dword_max
local highPartDiff as longint
highPartDiff := ah-bh
do case
case highPartDiff == 0
do case
case al==bl
return 0u
case al<bl
// wtf?
return maxdword
otherwise
return al-bl
endcase
case highPartDiff == 1
if al>= bl
// would be a overflow
return maxdword
else
return al + (maxdword-bl)
endif
case highPartDiff < 0
// wtf?
return maxdword
case highPartDiff > 1
// would be a overflow
return maxdword
endcase
return 0
If you go into .NET, don't use this. There is a lot better stuff there.