)]}'
{
  "commit": "b513bd808f9018da0609cffefaef451ea5c19a74",
  "tree": "235496d675ba14c893093af0fd4b2c9a4be1fefa",
  "parents": [
    "9eba17ff90963cdbbe47af887fb3152c0c4d1ebb"
  ],
  "author": {
    "name": "Michael Anthony Knyszek",
    "email": "mknyszek@google.com",
    "time": "Mon Feb 13 21:45:38 2023 +0000"
  },
  "committer": {
    "name": "Michael Knyszek",
    "email": "mknyszek@google.com",
    "time": "Tue Mar 21 19:27:18 2023 +0000"
  },
  "message": "runtime: bias the pacer\u0027s cons/mark smoothing against noise\n\nCurrently the pacer is designed to pace against the edge. Specifically,\nit tries to find the sweet spot at which there are zero assists, but\nsimultaneously finishes each GC perfectly on time.\n\nThis pretty much works, despite the noisiness of the measurement of the\ncons/mark ratio, which is central to the pacer\u0027s function. (And this\nnoise is basically a given; the cons/mark ratio is used as a prediction\nunder a steady-state assumption.) Typically, this means that the GC\nmight assist a little bit more because it started the GC late, or it\nmight execute more GC cycles because it started early. In many cases the\nmagnitude of this variation is small.\n\nHowever, we can\u0027t possibly control for all sources of noise, especially\nsince some noise can come from the underlying system. Furthermore, there\nare inputs to the measurement that have effectively no restrictions on\nhow they vary, and the pacer needs to assume that they\u0027re essentially\nstatic when they might not be in some applications (i.e. goroutine\nstacks).\n\nThe result of high noise is that the variation in when a GC starts is\nmuch higher, leading to a significant amount of assists in some GC\ncycles. While the GC cycle frequency basically averages out in the\nsteady-state in the face of this variation, starting a GC late has the\nsignificant drawback of reducing application latencies.\n\nThis CL thus biases the pacer toward avoiding assists by picking a\ncons/mark smoothing function that takes the maximum measured cons/mark\nover 5 cycles total. I picked 5 cycles because empirically this was the\nbest trade-off between window size and smoothness for a uniformly\ndistributed jitter in the cons/mark signal. The cost here is that if\nthere\u0027s a significant phase change in the application that makes it less\nactive with the GC, then we\u0027ll be using a stale cons/mark measurement\nfor 5 cycles. I suspect this is fine precisely because this only happens\nwhen the application becomes less active, i.e. when latency matters\nless.\n\nAnother good reason for this particular bias is that even though the GC\nmight start earlier and end earlier on average, resulting in more\nfrequent GC cycles and potentially worse throughput, it also means that\nit uses less memory used on average. As a result, there\u0027s a reasonable\nworkaround in just turning GOGC up slightly to reduce GC cycle\nfrequency and bringing memory (and hopefully throughput) levels back to\nthe same baseline. Meanwhile, there should still be fewer assists than\nbefore which is just a clear improvement to latency.\n\nLastly, this CL updates the GC pacer tests to capture this bias against\nassists and toward GC cycles starting earlier in the face of noise.\n\nSweet benchmarks didn\u0027t show any meaningful difference, but real\nproduction applications showed a reduction in tail latencies of up\nto 45%.\n\nUpdates #56966.\n\nChange-Id: I8f03d793f9a1c6e7ef3524d18294dbc0d7de6122\nReviewed-on: https://go-review.googlesource.com/c/go/+/467875\nTryBot-Result: Gopher Robot \u003cgobot@golang.org\u003e\nReviewed-by: Michael Pratt \u003cmpratt@google.com\u003e\nRun-TryBot: Michael Knyszek \u003cmknyszek@google.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "d2921f4ed3757e75acae4de8c58d845e69ed1deb",
      "old_mode": 33188,
      "old_path": "src/runtime/mgcpacer.go",
      "new_id": "8b6ad4d66ff6c0e524015f12d4d96086552d4056",
      "new_mode": 33188,
      "new_path": "src/runtime/mgcpacer.go"
    },
    {
      "type": "modify",
      "old_id": "e373e324a40f076b964a8532413b71c0e0b151d2",
      "old_mode": 33188,
      "old_path": "src/runtime/mgcpacer_test.go",
      "new_id": "ac2a3fa56cc0022135c16f7a2d4d55bf32b198af",
      "new_mode": 33188,
      "new_path": "src/runtime/mgcpacer_test.go"
    }
  ]
}
