Page MenuHomeFreeBSD

time(3): Align fast clock times to avoid firing multiple timers.
ClosedPublic

Authored by hselasky on Oct 3 2022, 9:17 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Oct 18, 6:36 AM
Unknown Object (File)
Wed, Oct 16, 11:36 AM
Unknown Object (File)
Wed, Oct 16, 11:36 AM
Unknown Object (File)
Wed, Oct 16, 11:35 AM
Unknown Object (File)
Wed, Oct 16, 11:05 AM
Unknown Object (File)
Oct 2 2024, 3:03 PM
Unknown Object (File)
Sep 30 2024, 8:33 AM
Unknown Object (File)
Sep 27 2024, 1:14 AM

Details

Summary

In non-periodic mode absolute times fire exactly at the time given.
When specifying a fast clock, align the firing time so that less
timer interrupt events are needed.

MFC after: 1 week
Sponsored by: NVIDIA Networking

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This revision is now accepted and ready to land.Oct 3 2022, 3:07 PM
sys/kern/kern_umtx.c
759

Hans, while I don't object aligning the events (even though for user-space processes it may cause more scheduler work to push them between different cores), I think this change may cause premature wakeups. Since the fast clocks are updated on tc_tick, I am not sure we guarantee that for example CLOCK_SECOND will be updated exactly at the edge of the second and not return previous value. Also umtx_abs_timeout_init() reading "current" time, may get one up to the period back, so just adding to it user's relative timeout will likely create time in the past, causing early wakeup. That is why I've had to add full tc_tick_sbt and SBT_1S here. So to align the events and still be safe from being early you must add more than that, not less.

I made the same comments in D36857 . . .

Something to consider? :

It looks to me that the original code tried to minimize the number of divisions (and modulo's). This might have been because of the likes of, say, "ARMv7-A implementation that does not include the Virtualization Extensions" having SDIV and UDIV as optional in the profile and ARMv7-R only requiring such instructions for Thumb, not ARM. (Just examples, I've no general knowledge of the range of platform's status for such.)

I also wonder if factor or divisor or the like is intended to ever allowed to be negative in the use of %. (Some routines have signed types involved.) Checking C's language requirements for negatives involved in % operations could be important otherwise: If there is C implementation freedom, that could lead to variability in the results.

Looks like C89 was the last with "implementation defined" for / and % involving negative integers. After that: 7/3==2; 7%3==1; -7/3==-2; -7%3==-1; 7/-3==-2; 7/-3==1; -7/-3==2; -7%-3==-1. So / truncates towards zero and a%b==a-(a/b)*b when a/b is representable. Notably -7%3!=7%-3 and 7%3!=-7%-3 .

sys/kern/kern_umtx.c
759

@mav :

If the timers wakeup too early, and then re-trigger, they will most likely get "phase locked", and then the next timeout will be correct, so I'm not so worried about that.

What I observe is that the timers are always delayed. If you ask for interrupt on time X, it will most likely be passed when the timer thread is invoked. This also has to do with passing deltas to the triggering mechanism itself, instead of absolute times.

I can wait a bit more before MFC'ing anything. It this change turns out to be troublesome I'll revert it.

Combined with the other time(3) changes I've made I see some good overall system improvements here for my desktop computers.

I made the same comments in D36857 . . .

Something to consider? :

It looks to me that the original code tried to minimize the number of divisions (and modulo's). This might have been because of the likes of, say, "ARMv7-A implementation that does not include the Virtualization Extensions" having SDIV and UDIV as optional in the profile and ARMv7-R only requiring such instructions for Thumb, not ARM. (Just examples, I've no general knowledge of the range of platform's status for such.)

I also wonder if factor or divisor or the like is intended to ever allowed to be negative in the use of %. (Some routines have signed types involved.) Checking C's language requirements for negatives involved in % operations could be important otherwise: If there is C implementation freedom, that could lead to variability in the results.

Looks like C89 was the last with "implementation defined" for / and % involving negative integers. After that: 7/3==2; 7%3==1; -7/3==-2; -7%3==-1; 7/-3==-2; 7/-3==1; -7/-3==2; -7%-3==-1. So / truncates towards zero and a%b==a-(a/b)*b when a/b is representable. Notably -7%3!=7%-3 and 7%3!=-7%-3 .

When you divide and multiply by constants, the compiler will optimize this. Have you looked at the resulting assembly code using -O2 ?

@mav

I think it is better to wakeup and do a bunch of work, and then go to sleep. Instead of having shorter sleeps with spread load. I'm thinking about the CPU idle stuff which affects the CPU states.

When you divide and multiply by constants, the compiler will optimize this. Have you looked at the resulting assembly code using -O2 ?

I understand for CLOCK_SECOND and "rem = *sbt % SBT_1S;": SBT_1S is a constant.

But for "rem = *sbt % tc_tick_sbt;" no such constant is involved. On armv7, for example, it would generate/use a more expensive __aeabi_uldivmod call (or some such) that the original code would not.