Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gc enhancements #261

Closed
StefanKarpinski opened this issue Nov 12, 2011 · 10 comments
Closed

gc enhancements #261

StefanKarpinski opened this issue Nov 12, 2011 · 10 comments
Assignees
Labels
performance Must go faster
Milestone

Comments

@StefanKarpinski
Copy link
Member

Some ideas for making GC faster/better:

  • Store cached type inference trees in a bytecode format instead of as a Julia objects on the heap.
  • Track escape bits (approximate ref counts) for objects, allowing immediate reclamation of unescaped objects.
@ghost ghost assigned JeffBezanson Nov 12, 2011
JeffBezanson added a commit that referenced this issue Dec 14, 2011
part of issue #261
significantly cuts the number of live objects, making GC much faster
StefanKarpinski added a commit that referenced this issue Dec 14, 2011
* 'master' of github.com:JuliaLang/julia:
  closing issue #197, hex literals give unsigned ints sized by digits
  storing ASTs serialized to save memory part of issue #261 significantly cuts the number of live objects, making GC much faster
@JeffBezanson
Copy link
Member

GC now 2x faster due to half as many live objects. Another idea:

  • Use compacting collector for small objects

@ViralBShah
Copy link
Member

Is it also possible for the compiler to insert calls to free objects that are easily proven as temporary in a code block? That would make it possible for them to be reused in the case of loops (with the allocator being aware), and reduce the load on GC in general.

@StefanKarpinski
Copy link
Member Author

That's the idea behind the escape bit tracking. If the object hasn't escaped by the time a function exists, you can free it.

@JeffBezanson
Copy link
Member

Here's another idea I plan to implement that also takes advantage of the escape bit.

Observation: a lot of garbage was only ever referenced by the stack. Examples include re-assigned local variables, and temporaries that were only function arguments, as in a+b+c+d.

The vast majority of GC time is in traversing the object graph. So we can do a quick "minor collection" by shallow marking (just setting the mark bit on one object and not recurring inside) objects on the stack, then doing a sweep where we free objects neither marked nor escaped. This will free most young garbage in a fraction of the time, giving most of the benefit of generational collection without needing to move objects.

@StefanKarpinski
Copy link
Member Author

This sounds great, but I don't understand the core of the technique:

So we can do a quick "minor collection" by shallow marking (just setting the mark bit on one object and not recurring inside) objects on the stack, then doing a sweep where we free objects neither marked nor escaped.

Can you expand on that?

@JeffBezanson
Copy link
Member

The idea is to be able to free "obvious garbage" without needing to traverse every live object in the system. Every live object is referenced from either the stack or the heap. The escape bit marks the heap-referenced objects (plus some that may be dead). So if we mark just the stack roots (local variables and arguments), every live object is now either marked or has its escape bit set. Objects with neither are the recently-dead, like the first a in this sequence:

a = zeros(n,n)
a = zeros(n,n)

@StefanKarpinski
Copy link
Member Author

Ah, I think I see what you're saying now. This relies on the mark-and-sweep having already occurred and having mark bits still set?

@JeffBezanson
Copy link
Member

No. The escape bit is set when an object is referenced from the heap, and stays set for the object's whole life.
I will write a new procedure minor_gc that sets the mark bit on direct stack objects, then does a sweep but only frees objects with neither bit set. Sweep will still un-set any mark bits it finds set, but of course leaves escape bits alone.

@ViralBShah
Copy link
Member

What is the current thinking on this one? Implement minor_gc and perhaps other things? Is it possible to have a gc benchmark where such things can be measured?

@JeffBezanson
Copy link
Member

Closed by #8699

StefanKarpinski pushed a commit that referenced this issue Feb 8, 2018
* adds AsyncCondition that's more compliant with 0.5 version

* fixes AsyncCondition on v0.3. also makes tests more deterministic

There were a couple `sleep(0.1)` calls in the AsyncCondition tests that I've now swapped out for more explicit Condition-based task switching.
LilithHafner pushed a commit to LilithHafner/julia that referenced this issue Oct 11, 2021
* Added `cor2cov` and `cov2cor` methods.

* Switched to accepting `AbstractMatrix` vs `DenseMatrix`.

* Added an in-place version of cor2cov and update the docs to mention the in-place versions.

* Added in-place specific tests.
cmcaine added a commit to cmcaine/julia that referenced this issue Nov 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster
Projects
None yet
Development

No branches or pull requests

3 participants