faster-cpython / ideas

1.67k stars 49 forks source link

Incremental cycle GC #613

Closed markshannon closed 2 months ago

markshannon commented 11 months ago

The cycle GC takes about 10% of the runtime on our benchmark suite. This is already far too high, and with NoGIL it will get much worse.

Currently, we perform an entire heap scan every N collections (currently N == 100). Scanning the entire heap is bad for throughput and even worse for latency.

So instead of scanning the entire heap at once, we should scan the old generation incrementally.

Here's how it could work (this untested and unproven)

clear_cycles_and_restore_refcounts(work) is already part of the cycle GC, so we aren't really adding much complexity.

The above algorithm has (I believe) two key properties:


[*] Instead of doing an incremental collection every 2 collections, we could do it every N collections. If the incremental collections visit too many objects, i.e. much more than work_per_collection, we can increase N.