[Bug 262215] Two imprecisions in cputime counters
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 262215] Two imprecisions in cputime counters"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 26 Feb 2022 23:11:31 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=262215 Bug ID: 262215 Summary: Two imprecisions in cputime counters Product: Base System Version: 13.0-RELEASE Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: firk@cantconnect.ru Created attachment 232127 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=232127&action=edit patch for 10.4 - 14-CURRENT ====== kern_tc.c/cputick2usec() ====== > uint64_t cputick2usec(uint64_t tick) { > if (tick > 18446744073709551LL) /* floor(2^64 / 1000) */ > return (tick / (cpu_tickrate() / 1000000LL)); > else if (tick > 18446744073709LL) /* floor(2^64 / 1000000) */ > return ((tick * 1000LL) / (cpu_tickrate() / 1000LL)); > else > return ((tick * 1000000LL) / cpu_tickrate()); > } There is huge precision loss from dividing cpu_tickrate() by 1000 or 1000000 (up to 0.025% in the second case for 4GHz CPU). Worse, it will result in useconds step after reaching these two thresholds. Let's see: CPU 3999999999 Hz tick = 18446744073709 (real time 1:16:51.686019) usec = 18446744073709*1000000/3999999999 = 4611686019 = 1:16:51.686019 next usec = 18446744073710*1000/3999999 = 4611687171 = 1:16:51.687171 diff = 1152 usec (not so big, and such a step may be caused by a lot of sources anytime, but it is a fake step anyway) tick = 18446744073709551 (real time 53D 9:01:26.019580) usec = 18446744073709551*1000/3999999 = 4611687171349 = 53D 9:01:27.171349 (note already 1 sec imprecise) next usec = 18446744073709552/3999 = 4612839228234 = 53D 9:20:39.228234 diff = 19 minutes! ====== kern_time.c/cputick2timespec() ====== (it is used for clock_gettime() for querying process or thread consumed cpu time) Uses cputick2usec() and then needlessly converting usec to nsec, obviously losing precision even with fixed cputick2usec(). ====== kern_time.c/kern_clock_getres() ====== Uses some weird (anyway wrong) formula for getting cputick resolution. ------- patch attached the patch was done for 12.3, but may be applied succesfully to any version from 10.4 to CURRENT -- You are receiving this mail because: You are the assignee for the bug.