Re: How do get elapsed time in milliseconds in a shell script?
- In reply to: Steve O'Hara-Smith : "Re: How do get elapsed time in milliseconds in a shell script?"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 20 Jul 2022 15:35:42 UTC
On 19 July 2022 12:42:27 am AEST, Steve O'Hara-Smith <steve@sohara.org> wrote: > On Mon, 18 Jul 2022 14:01:01 +0100 > freebsd-doc@fjl.co.uk wrote: > > > I think what may be needed is a base utility to produce the > accurate > > tick since the epoch or boot - it doesn't' matter for timeing. > Possibly > > an extension to "uptime", which I assume must know. > > There are some counters exposed via sysctl which might be useful, > kern.timecounter.tc.HPET.counter looks promising, the rest seem to > cycle > rather quickly. Of course portability is an issue with using these. I must admit to being puzzled as to the efficacy of looking for millisecond precision for event timing or uptime on a non-realtime OS, when there are so many things that bend time going on. Sure, the kernel has a pretty good idea of what's what and when's when, but out here in userland it's pretty fluid. One's system may have a good lock to network time, at boot anyway, but once we're talking about something that can be called up in a script, anything past 100ms is slippery. In concord about HPET being the likely best timecounter for this, if it's also on non-Intel systems? So I've had a bit of a play in the script below. HPET wraps at ~300 seconds, so anything longer term has to be driven by interrupts off that. We have kernel hackers for that ... Anyway, I think running this should illustrate, if nothing else, the vagaries of userland timesharing especially in scripts. This tested on 12.3-RELEASE, 2.6GHz i5 3320M, otherwise idle. Also, csh's time command already reports millisecond system and user times, with decisecond elapsed time for process timing; it's in base; and can be invoked from sh by such as $ csh -c 'time sh -c "${myscript}"' cheers, Ian * tabs may not survive pasting <code> #!/bin/sh # kern.timecounter.tc.HPET.frequency: 14318180 period: 69.841ns # kern.timecounter.tc.HPET.mask: 4294967295 repeat: 299.966s period=69.841 # ns [ "$1" ] && j="$1" || j=25 j=$((j+1)) for i in `jot - 1 $j`; do this=`sysctl -n kern.timecounter.tc.HPET.counter` if [ $i -eq 1 ]; then echo "this prev step msec" else step=`echo "scale=12; $this - $prev" | bc` msec=`echo "scale=3; $step * $period / 10^6" | bc` echo "$this $prev $step $msec" fi prev=$this done exit 0 </code>