Recent

Author Topic: [SOLVED] Getting the current time in form of nanoseconds count as Int64  (Read 9338 times)

furious programming

  • Hero Member
  • *****
  • Posts: 853
I need to get the time with nanosecond precision from the system to be able to measure the duration of the set of operations being performed (multiplatform project). I found this site in documentation — Using Kernel Time Abstractions — in which the set of appropriate functions is given.

The clock_get_system_nanotime function will be suitable for my needs. Unfortunately, I have not found in the web a single example of its use in Free Pascal. I do not know if it is imported in any unit for the FPC or not. I do not have a computer with macOS at hand and I do not know this system, so I can not check it myself.

Can any of the experts of this system show me an example of using the function clock_get_system_nanotime?

The only thing I would like to know is how to get the current time and convert it to the total number of nenoseconds in the form of Int64. And also what units must be included to access this function (or an example of an import declaration) and the required data types.

Thank you for all the help.
« Last Edit: April 22, 2019, 01:39:14 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #1 on: April 17, 2019, 02:09:26 am »
I think you will struggle to find a cross platform nanosecond measurement model.

Most people use GetTickCount64() to measure at the millisecond level. Beyond that the overhead of your measurement comes into play.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

furious programming

  • Hero Member
  • *****
  • Posts: 853
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #2 on: April 17, 2019, 02:16:43 am »
I think you will struggle to find a cross platform nanosecond measurement model.

Yes, that's why I have to use different functions on different platforms. Windows and Linux is done, macOS remained.

Quote
Most people use GetTickCount64() to measure at the millisecond level.

Millisecond precision is not enough. The more so that the precision of the system clock is too low (and depends on the platform/OS) for the millisecond result to be worth anything. I need to measure the duration of the operation being performed, which may be less than one millisecond.

Generally, I need the equivalent of the QueryPerformanceCounter function from Windows or clock_gettime (for example with CLOCK_MONOTONIC) from Linux. All solutions working with milliseconds precision are impossible to use.
« Last Edit: April 17, 2019, 02:22:09 am by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #3 on: April 17, 2019, 02:38:11 am »
Upfront: I don't have an answer for your question.

I have another question instead:

Millisecond precision is not enough.
If your program is running on a multitasking O/S, it is subject to whatever the scheduler decides to do.  In such cases, even when the measurement is very precise, it is hard to say that it is representative of anything.  Of course, you can take averages, drop large variations but, no matter what you do, the measurements, whatever they may be, will vary a great deal making them of questionable use.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thausand

  • Sr. Member
  • ****
  • Posts: 292
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #4 on: April 17, 2019, 03:42:23 am »
Yes, that's why I have to use different functions on different platforms. Windows and Linux is done, macOS remained.
Look epiktimer http://wiki.lazarus.freepascal.org/EpikTimer

I no think Epiktimer have support MacOS. But MacOS have precision time read https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html

I not have MacOS and maybe some can try and have macOS ?

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #5 on: April 17, 2019, 05:56:17 am »
Well spotted Thausand !

Its in the OnlinePackageManager, so easy install. I'll try it out on my battered old Mac and see what I get.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #6 on: April 17, 2019, 06:49:34 am »

OK, works fine on the Mac, see -

Code: Pascal  [Select][+][-]
  1. procedure TForm1.SpeedButton1Click(Sender: TObject);
  2. var
  3.   ET: TEpikTimer;   // Need to add etpackage to project requirements
  4. begin
  5.   ET := TEpikTimer.Create(Application);
  6.   ET.Clear();
  7.   ET.Start;
  8.   Sleep(1);
  9.   ET.Stop;
  10.   showmessage('1ms = ' + FloatToStr(ET.Elapsed));
  11. end;    

Tells me that 1mS=0.001166 (seconds)

That is, of course, 1,166 microseconds. Subsequent runs - 0.001155; 0.001085; 0.001147; 0.001221; 0.001133

Replace the sleep with a single debugln() line, we get - 0.000042; 0.000036; 0.000034; 0.000046; 0.000022

The noise at microsecond levels would seem to make nanosecond measurements beyond reasonable expectations. But as a tool for measuring microseconds, it looks pretty good ! 

The number returned is a float, so you can, if you wish, extract any resolution you want from it, but don't confuse that with precision !

This, on a 2012 Macbook pro, Lazarus 2.0.2

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #7 on: April 17, 2019, 09:09:52 am »
[DELETED]
« Last Edit: April 18, 2019, 03:30:38 am by engkin »

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #8 on: April 17, 2019, 12:51:40 pm »
Is the task something you can repeat? Perform the same thing 10000 times and then the millisecond time will be meaningful enough. Single iteration then actually takes total time divided by 10000.

furious programming

  • Hero Member
  • *****
  • Posts: 853
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #9 on: April 17, 2019, 06:09:48 pm »
If your program is running on a multitasking O/S, it is subject to whatever the scheduler decides to do. […]

This is obvious, I know that and no, it does not bother me at all. I do not use these results for statistics.


Look epiktimer http://wiki.lazarus.freepascal.org/EpikTimer

I've seen the code of this timer many of times. For macOS uses GetTickCount64, and I do not want to use this function because its result is not a predetermined time unit and depends on platform/OS/hardware/whatever.

Quote
But MacOS have precision time read https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html

Just to this documentation site I've provided a link in the first post of this thread...


Have you read what I asked for at all? Come on guys... I asked a specific question. I do not need advice on what to choose, I do not need an assembler (probably), and I certainly do not need to attach to the project a thousand lines of someone else's code just to use its 10 lines.

I know exactly what function I need to use, I know that it is available and that it meets all assumptions. So I will ask again — is there anyone here who can give a specific, short and simple example of using the function clock_get_system_nanotime?
« Last Edit: April 17, 2019, 08:44:59 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #10 on: April 17, 2019, 06:26:37 pm »
If your program is running on a multitasking O/S, it is subject to whatever the scheduler decides to do. […]
This is obvious, I know that and no, it does not bother me at all.

I agree that is, or at least should be, obvious. 

The problem is, it won't accomplish the goal stated in your original post:
I need to get the time with nanosecond precision from the system to be able to measure the duration of the set of operations being performed (multiplatform project).
It is obvious you will not get nanosecond precision - because the O/S scheduler is (obviously) going to get in the way.

Just for the record, in spite of the above, if I had an example of what you requested, I'd provide it to you.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #11 on: April 17, 2019, 06:51:50 pm »
exact nano or pico resolution is usually done with dedicated hardware. RTOS systems. FPC can do that with embedded.
For multi-tasking systems: don't get your hopes up.
Specialize a type, not a var.

furious programming

  • Hero Member
  • *****
  • Posts: 853
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #12 on: April 17, 2019, 07:05:14 pm »
It is obvious you will not get nanosecond precision - because the O/S scheduler is (obviously) going to get in the way.

Precision will be nanosecond, because the result will be the number of nanoseconds (which, after all, provides the mentioned function). At most, it will deviate from reality to some extent — I know that.

In my case, if the deviation from the actual measurement will not be greater than, let's assume, 0.1ms, it will not cause noticeably malfunction of the program. Noticeably, because it is about the perception of the human eye, not about the possibility of errors in the program. And I suspect that in typical conditions such large distortions do not occur (more than assumed 100000ns). But if so, the worst thing that can happen is a normal lag, that will not destabilize the program in any way.

I care more specifically about the function clock_get_system_nanotime, because it returns the result in nanoseconds (in a known unit of time), which then I can use in the function FpNanoSleep, without any complex calculations, rounding and similar. Just one multiplication and done. The final code will be short and easy to understand for everyone (including me), and this is importontant (at least for me).

Quote
Just for the record, in spite of the above, if I had an example of what you requested, I'd provide it to you.

I appreciate. In the meantime, I will try to write it myself, but I still will not be able to check it out in practice, so I will ask for a test.
« Last Edit: April 17, 2019, 07:17:57 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

furious programming

  • Hero Member
  • *****
  • Posts: 853
Re: Getting the current time in form of nanoseconds count as Int64
« Reply #13 on: April 17, 2019, 08:29:04 pm »
This should be enough:

Code: Pascal  [Select][+][-]
  1. unit CustomTimeUtils;
  2.  
  3. {$MODE OBJFPC}{$LONGSTRINGS ON}
  4.  
  5. interface
  6.  
  7.   procedure clock_get_system_nanotime(secs, nanosecs: puint32); cdecl; external 'libname'{?};
  8.  
  9.   function TimeInNanoseconds(): Int64;
  10.  
  11. implementation
  12.  
  13. function TimeInNanoseconds(): Int64;
  14. var
  15.   Seconds: UInt32 = 0;
  16.   Nanoseconds: UInt32 = 0;
  17. begin
  18.   clock_get_system_nanotime(@Seconds, @Nanoseconds);
  19.   Result := Int64(Seconds) * 1000000000 + Int64(Nanoseconds);
  20. end;
  21.  
  22. end.

But I do not know the library name (highlighted line) — someone knows it? And simple program to test:

Code: Pascal  [Select][+][-]
  1. program TimeTest;
  2.  
  3. {$MODE OBJFPC}{$LONGSTRINGS ON}
  4.  
  5. uses
  6.   SysUtils, CustomTimeUtils;
  7. var
  8.   I: Integer;
  9. begin
  10.   WriteLn(TimeInNanoseconds());
  11.  
  12.   for I in [0 .. 9] do
  13.   begin
  14.     Sleep(1000);
  15.     WriteLn(TimeInNanoseconds());
  16.   end;
  17.  
  18.   ReadLn();
  19. end.

The results given in individual loop iterations should more or less differ by 1 billion.

A test project in the attachment. Can anyone set the proper name of the library, check if it compile and works, and show the console output? I will be grateful.
« Last Edit: April 17, 2019, 08:32:19 pm by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

sstvmaster

  • Sr. Member
  • ****
  • Posts: 299
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

 

TinyPortal © 2005-2018