[HN Gopher] Introduction to Golang Preemption Mechanisms
       ___________________________________________________________________
        
       Introduction to Golang Preemption Mechanisms
        
       Author : lcof
       Score  : 38 points
       Date   : 2024-08-11 17:23 UTC (5 hours ago)
        
 (HTM) web link (unskilled.blog)
 (TXT) w3m dump (unskilled.blog)
        
       | zbentley wrote:
       | Interesting that it's temporal (according to the article, you
       | have around 10 microseconds before the signal-based preempter
       | kicks in). How bad is performance if the load on the host is so
       | high that double-preempting is common, I wonder? Or am I missing
       | something and that question is not meaningful?
        
         | lcof wrote:
         | No it's an interesting comment. This is not really about load,
         | but about control flow: if goroutine is just spinning wild
         | without going through any function prologue, it won't even be
         | aware of the synchronous preemption request. Asynchronous
         | preemption (signal-based) is mainly (I say "mainly" because I
         | am not sure I can say "only") for this kind of situation.
         | 
         | I don't have the link ready, but twitch had this kind of issue
         | with base64 decoding in some kind of servers. The GC would try
         | to STW, but there would always be one or a few goroutines
         | decoding base64 in a tight loop for the time STW was attempted,
         | delaying it again and again.
         | 
         | Asynchronous preemption is a solution to this kind of issue.
         | Load is not the issue here, as long as you go through the
         | runtime often enough.
        
       | __turbobrew__ wrote:
       | Are there any proposals to make the golang runtime cgroup aware?
       | Last time I checked the go runtime will spawn a OS process for
       | each cpu it can see even if it is running in a cgroup which only
       | allows 1 CPU of usage. On servers with 100+ cores I have seen
       | scheduling time take over 10% of the program runtime.
       | 
       | The fix is to inspect the cgroupfs to see how many CPU shares you
       | can utilize and then set gomaxprocs to match that. I think other
       | runtime like Java and .NET do this automatically.
       | 
       | It is the same thing with GOMEMLIMIT, I don't see why the runtime
       | does not inspect cgroupfs and set GOMEMLIMIT to 90% of the cgroup
       | memory limit.
        
         | jrockway wrote:
         | I am guessing the API isn't stable enough for letting the
         | runtime set maxprocs. I use
         | https://pkg.go.dev/go.uber.org/automaxprocs and have had to
         | update it periodically because Redhat and Debian have different
         | defaults. (Should one even run k8s on Redhat? I say no, but
         | Redhat says yes. That's how I know about this.)
         | 
         | This, I think, is cgroups 1 vs. cgroups 2 and everyone should
         | have cgroups 2 now, but ... it would feel weird for the Go
         | runtime to decide on one. To me, anyway.
        
           | __turbobrew__ wrote:
           | Which API is not stable? Cgroupfs?
           | 
           | I would think that cgroupfs is considered an API to userspace
           | and therefore it shouldn't break in the future? Hence
           | creating cgroups v2?
           | 
           | I have written code which handles both cgroups v1 and cgroups
           | v2, it isn't terribly hard. Golang could also only support
           | setting automatic parameters when running in cgroups v2 if
           | that made things easier.
           | 
           | For a language that prides itself in sane defaults I think
           | they have missed the mark here. I could probably add support
           | to the golang runtime in a few hundred lines of code and
           | probably save millions of dollars and megawatts of energy
           | because the go runtime is not spawning 50 processes to run a
           | program which is constrained to 1 core.
        
         | lcof wrote:
         | On Linux, go uses sched_getaffinity to know how many cpu core
         | it is allowed to run on:
         | 
         | https://cs.opensource.google/go/go/+/master:src/runtime/os_l...
        
       | ollien wrote:
       | Great post! One question that lingered for me is: what are
       | asynchronous safe-points? The post goes into some detail about
       | their synchronous counterparts
        
       ___________________________________________________________________
       (page generated 2024-08-11 23:00 UTC)