Recent

Author Topic: High resolution timing - Apple Silicon  (Read 927 times)

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
High resolution timing - Apple Silicon
« on: June 24, 2025, 04:37:02 pm »
I continue to be frustrated by the coarse timing generally available from the fpc sysutils GetTickCount64 function in MacOS.  (1ms).

I stumbled upon this article (link at bottom) and it suggests that nanosecond level timing can be achieved using a C++ package (that I have not delved into, C being a minor ability and C++ being only of flirting acquaintance or maybe a glance across a crowded room).

1) Anyone care to try to link or adapt for FPC?

2) Is this something that could be implemented in a simpler fashion at the compiler level?  Seems very useful to me - recognizing that it would not be generally portable - though the article suggests adaptability to Linux systems and possibly Windows/x86_64.

    a) A compiler directive to test for compatibility.
    b) a function to get the tick resolution (How many ticks per second)
    c) a function similar to GetTickCount64 ... call it GetTickCountHighResolution;

Unlike GetTickCount64 which is ms since Unix 0 date in the past (1 Jan, 1970 ish), this new function would be ticks since the computer started.


https://lemire.me/blog/2023/03/21/counting-cycles-and-instructions-on-arm-based-apple-systems/
« Last Edit: June 24, 2025, 05:16:31 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

gues1

  • Jr. Member
  • **
  • Posts: 77
Re: High resolution timing - Apple Silicon
« Reply #1 on: June 24, 2025, 05:41:26 pm »
For Intel processor I had done that (in assembler) and use it in same cases, for ARM I don't know.
But I think that MacOS with arm still have the QPC (I mean high precision timer) that one can use.

It has to resolution of 0,1 microseconds and works in Hardware, not in software or inside the CPU.

This is a link where I attached a Unit in Pascal that works with Windows and Linux. Someone can adapt it for MacOs.

https://forum.lazarus.freepascal.org/index.php/topic,71540.msg558558.html#msg558558

Thaddy

  • Hero Member
  • *****
  • Posts: 17379
  • Ceterum censeo Trump esse delendam
Re: High resolution timing - Apple Silicon
« Reply #2 on: June 24, 2025, 05:51:38 pm »
Modern Apple hardware does have hardware timers, but abstracted away in the OS with:
mach_absolute_time()  gives access to a continuously incrementing counter with nanosecond-level resolution.

clock_gettime()  POSIX-compliant and useful for portable high-resolution timing.

dispatch_time()  part of Grand Central Dispatch for scheduling.
In MacOS these are backed by the hardware timers.
I think you can not get at the hardware timers directly.
« Last Edit: June 24, 2025, 05:55:49 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

gues1

  • Jr. Member
  • **
  • Posts: 77
Re: High resolution timing - Apple Silicon
« Reply #3 on: June 24, 2025, 06:07:33 pm »
Modern Apple hardware does have hardware timers, but abstracted away in the OS with:

Someone with MacOs hw can adapt the Diagnostics unit so it works with MacOs too, I think is a good thing.

I don't think that is necessary a lot of works, but would need a MacOs PC.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
Re: High resolution timing - Apple Silicon
« Reply #4 on: June 24, 2025, 06:44:58 pm »
Modern Apple hardware does have hardware timers, but abstracted away in the OS with:
mach_absolute_time()  gives access to a continuously incrementing counter with nanosecond-level resolution.

clock_gettime()  POSIX-compliant and useful for portable high-resolution timing.

dispatch_time()  part of Grand Central Dispatch for scheduling.
In MacOS these are backed by the hardware timers.
I think you can not get at the hardware timers directly.

I don't mind much that it's "abstracted away" in the OS, it would still be far better than my current use case.

Is it possible to link to the kernel/mach API with a command line C compile?  Or does one have to slog into XCode?
(Yes - I'm completely lost in the woods here).

Is there a simple C example that I could attempt to link to? 
I'd create a useful unit from that if so (after stumbling around figuring out calls to C from Pascal - it's been a stretch).
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

Thaddy

  • Hero Member
  • *****
  • Posts: 17379
  • Ceterum censeo Trump esse delendam
Re: High resolution timing - Apple Silicon
« Reply #5 on: June 24, 2025, 06:46:37 pm »
Yes, it is possible. Tomorrow I will knock something up. Dinner time.
You only need pure FreePascal, nothing extra fancy.
(Come to think of it: I asked Jonas months ago for some small changes in the POSIX timer handling. That example will probably work OOTB.)
« Last Edit: June 24, 2025, 06:50:19 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
Re: High resolution timing - Apple Silicon
« Reply #6 on: June 24, 2025, 07:57:49 pm »
Yes, it is possible. Tomorrow I will knock something up. Dinner time.
You only need pure FreePascal, nothing extra fancy.
(Come to think of it: I asked Jonas months ago for some small changes in the POSIX timer handling. That example will probably work OOTB.)

That would be very kind.  Thank you!
No rush either.
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
Re: High resolution timing - Apple Silicon
« Reply #7 on: June 24, 2025, 08:43:24 pm »
For Intel processor I had done that (in assembler) and use it in same cases, for ARM I don't know.
But I think that MacOS with arm still have the QPC (I mean high precision timer) that one can use.

It has to resolution of 0,1 microseconds and works in Hardware, not in software or inside the CPU.

The 0.1 µs madness is a Microsoft invention, and IIRC is derived from h/w but scaled to that value in s/w.

It does have one redeeming feature that my very long winded post on GPS v. NTTP time testing gets into:
https://forum.lazarus.freepascal.org/index.php/topic,60420.msg452175.html#msg452175
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8453
Re: High resolution timing - Apple Silicon
« Reply #8 on: June 24, 2025, 10:06:14 pm »
Have you investigated the POSIX clock behaviour, as described at e.g. https://docs.redhat.com/en/documentation/red_hat_enterprise_linux_for_real_time/7/html/reference_guide/sect-posix_clocks ?

My recollection is that that specifies both the units of the syscall, and the best resolution (e.g. nanosec and microsecs respectively).

Now() returning a real number is inherently flawed in that the further you get from the epoch the less your resolution.

As an historical note, my understanding is that the internal clock of ye ancient IBM S/360 defined that on all models a certain bit /would/ be updated at a defined rate (for the sake of argument let's say once per millisecond), and that lesser bits /might/ be updated monotonically.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 17379
  • Ceterum censeo Trump esse delendam
Re: High resolution timing - Apple Silicon
« Reply #9 on: June 26, 2025, 08:37:37 am »
Small example, but it is more complicated. Compile with fpc -k"-framework Cocoa" machtimeexample.pas
But you need to transate the ticks to time with mach_timebase_info(), which I never used, (yet) but this code is the proper timer.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$modeswitch objectivec1}
  3.  
  4. program MachTimeExample;
  5.  
  6. uses
  7.   ctypes, MacOSAll, CocoaAll;
  8.  
  9. var
  10.   timebase: mach_timebase_info_data_t;
  11.   startTime, endTime, elapsedNano: UInt64;
  12.  
  13. begin
  14.   // Initialize the timebase info - necessary to convert ticks to nanoseconds
  15.   mach_timebase_info(@timebase);
  16.  
  17.   // Get the start time
  18.   startTime := mach_absolute_time();
  19.  
  20.   // Do some work you want to measure
  21.   // For example, a small delay
  22.   NSProcessInfo.processInfo.sleepForTimeInterval(0.5); // Sleep for 0.5 seconds
  23.  
  24.   // Get the end time
  25.   endTime := mach_absolute_time();
  26.  
  27.   // Calculate elapsed time in nanoseconds
  28.   elapsedNano := (endTime - startTime) * UInt64(timebase.numer) div UInt64(timebase.denom);
  29.  
  30.   writeln('Start time: ', startTime, ' ticks');
  31.   writeln('End time:   ', endTime, ' ticks');
  32.   writeln('Elapsed:    ', elapsedNano, ' nanoseconds');
  33.   writeln('            ', elapsedNano / 1000000:0:3, ' milliseconds');
  34. end.
This one is tested, the rest I have to find out....
.....Like you... 8)
My Apple mini is just a toy for these kind of things. I am no expert in that sense.
« Last Edit: June 26, 2025, 08:56:13 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
Re: High resolution timing - Apple Silicon
« Reply #10 on: June 26, 2025, 03:45:33 pm »
Thanks,

Won't compile. (  fpc -k"-framework Cocoa" macht   )

I assume I need to update to fpc 3.3.1 or better, I'll get around to that later (issues with that as well).

The translation step is consistent with other systems where a 'scale factor' is needed to translate 'ticks' to time in seconds.

Will be interesting to see if this ports back to intel as well with a re-compile there.
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

Thaddy

  • Hero Member
  • *****
  • Posts: 17379
  • Ceterum censeo Trump esse delendam
Re: High resolution timing - Apple Silicon
« Reply #11 on: June 26, 2025, 04:15:44 pm »
Thanks,

Won't compile. (  fpc -k"-framework Cocoa" macht   )

I assume I need to update to fpc 3.3.1 or better, I'll get around to that later (issues with that as well).

The translation step is consistent with other systems where a 'scale factor' is needed to translate 'ticks' to time in seconds.

Will be interesting to see if this ports back to intel as well with a re-compile there.
I will look into it. When I tested it worked.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 17379
  • Ceterum censeo Trump esse delendam
Re: High resolution timing - Apple Silicon
« Reply #12 on: June 26, 2025, 04:20:05 pm »
Try this, not mine for the correction:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$modeswitch objectivec1}
  3. {$linkframework CoreServices} // Add this line
  4.  
  5. program MachTimeExample;
  6.  
  7. uses
  8.   ctypes, MacOSAll, CocoaAll;
  9.  
  10. var
  11.   timebase: mach_timebase_info_data_t;
  12.   startTime, endTime, elapsedNano: UInt64;
  13.  
  14. begin
  15.   // Initialize the timebase info
  16.   if mach_timebase_info(@timebase) <> 0 then
  17.   begin
  18.     writeln('Error getting timebase info');
  19.     Exit;
  20.   end;
  21.  
  22.   // Get the start time
  23.   startTime := mach_absolute_time();
  24.  
  25.   // Do some work you want to measure
  26.   NSProcessInfo.processInfo.sleepForTimeInterval(0.5); // Sleep for 0.5 seconds
  27.  
  28.   // Get the end time
  29.   endTime := mach_absolute_time();
  30.  
  31.   // Calculate elapsed time in nanoseconds
  32.   elapsedNano := (endTime - startTime) * UInt64(timebase.numer) div UInt64(timebase.denom);
  33.  
  34.   writeln('Start time: ', startTime, ' ticks');
  35.   writeln('End time:   ', endTime, ' ticks');
  36.   writeln('Elapsed:    ', elapsedNano, ' nanoseconds');
  37.   writeln('            ', elapsedNano / 1000000:0:3, ' milliseconds');
  38. end.
Also tested and also works.
Otherwise I need an failing example - full code - that does not work.
My Apple is mostly idle.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

AlanTheBeast

  • Sr. Member
  • ****
  • Posts: 390
  • My software never cras....
Re: High resolution timing - Apple Silicon
« Reply #13 on: June 26, 2025, 06:45:01 pm »
Try this, not mine for the correction:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$modeswitch objectivec1}
  3. {$linkframework CoreServices} // Add this line
  4.  
  5. program MachTimeExample;
  6.  
  7. << code largely snipped >>>
  8.   writeln('Start time: ', startTime, ' ticks');
  9.   writeln('End time:   ', endTime, ' ticks');
  10.   writeln('Elapsed:    ', elapsedNano, ' nanoseconds');
  11.   writeln('            ', elapsedNano / 1000000:0:3, ' milliseconds');
  12. end.
Also tested and also works.
Otherwise I need an failing example - full code - that does not work.
My Apple is mostly idle.

With fpc 3.2.2 this version won't compile either.  I'll retry with 3.3.1 when I get it working.

Quote
/Users/alanbeast/pascal $ fpc -k"-framework Cocoa" machtimeexample
Free Pascal Compiler version 3.2.2 [2021/05/16] for aarch64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Darwin for AArch64
Compiling machtimeexample.pas
machtimeexample.pas(11,13) Error: Identifier not found "mach_timebase_info_data_t"
machtimeexample.pas(11,38) Error: Error in type definition
machtimeexample.pas(16,6) Error: Identifier not found "mach_timebase_info"
machtimeexample.pas(23,16) Error: Identifier not found "mach_absolute_time"
machtimeexample.pas(26,29) Error: identifier idents no member "sleepForTimeInterval"
machtimeexample.pas(29,14) Error: Identifier not found "mach_absolute_time"
machtimeexample.pas(32,58) Error: Illegal qualifier
machtimeexample.pas(32,85) Error: Illegal qualifier
machtimeexample.pas(38,4) Fatal: There were 8 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppca64 returned an error exitcode
/Users/alanbeast/pascal $
« Last Edit: June 26, 2025, 09:22:44 pm by AlanTheBeast »
Everyone talks about the weather but nobody does anything about it.
..Samuel Clemens.

 

TinyPortal © 2005-2018