Signal-based preemption latency in tight-loop goroutines
27.5K reputation · 10 Jul 2021, 12:59 UTC
Since Go 1.14, the runtime utilizes asynchronous preemption via OS signals to interrupt goroutines that exceed their time slice. While this prevents tight loops without function calls from starving the scheduler, high‑concurrency environments on many‑core systems frequently exhibit unpredictable tail latency spikes.
When many goroutines are executing CPU‑bound tight loops simultaneously, the overhead of delivering and handling signals across multiple P (Processor) structures can introduce significant jitter. This behavior is particularly pronounced when the scheduler must manage global run queue contention alongside local queue balancing, potentially delaying the execution of high‑priority tasks or Stop‑The‑World (STW) phases.
How does the overhead of signal‑based preemption scale relative to the number of active goroutines under heavy load?
Is there a documented threshold where the cost of signal‑driven context switching outweighs the benefits of non‑cooperative preemption?