Live data from Hacker News

Linus Torvalds on Garbage Collection (2002)

gcc.gnu.org

91–100 of 207 posts

Re: Linus Torvalds on Garbage Collection (2002)

#91
post #63

Earlier quoted context omitted.

Scaling Python on multiple cores is easy: you just run multiple Python processes, each with its own per-core GIL. You are correct, though, that ref-counting overhead is one of the main reasons Python is slow.

The drawback with multiple processes is that they each have all the compiled bytecode on their heap. When I "import nltk" my heap goes from ~12 to ~36 MB. Add a few more dependencies and you end up wasting a non-trivial amount of RAM on python heaps.

You could do the import and then fork the child processes. That should share all the memory used by the nitk module between all the children (for as long as the memory is not modified by anyone, which triggers a copy-on-write allocation of the affected pages).

Re: Linus Torvalds on Garbage Collection (2002)

#92
post #63

Earlier quoted context omitted.

Scaling Python on multiple cores is easy: you just run multiple Python processes, each with its own per-core GIL. You are correct, though, that ref-counting overhead is one of the main reasons Python is slow.

The drawback with multiple processes is that they each have all the compiled bytecode on their heap. When I "import nltk" my heap goes from ~12 to ~36 MB. Add a few more dependencies and you end up wasting a non-trivial amount of RAM on python heaps.

That's a valid point, but you can do things to mitigate this, like splitting up your program into processes that have different dependencies. For instance, if you have a UI process and a core logic process, you won't need to import your giant UI library twice.

Re: Linus Torvalds on Garbage Collection (2002)

#93
post #56
post #42

Earlier quoted context omitted.

Linus suggested in the OP that automated reference counting (where the language implementation handles reference counting for the programmer) is preferable to GC. Python uses such reference counting (although it also has a GC fallback to ensure cyclic structures are collected).

And it is one of the reason why python is slow and difficult to scale on multiple cores (the main difficulty by far of removing the GIL is reference counting).

C and Java apps with high contention don't scale well onto multiple cores, either.

The key to speed is to not share state, which Python can do fine. It's called fork.

Re: Linus Torvalds on Garbage Collection (2002)

#94

Here are a couple of reasons why I think it's not so clear cut: 1. If garbage collection was that damaging to the cache, Haskell wouldn't be nearly as fast as C. 2. Copy-on-write data structures are nice because the immutability allows for concurrent access without locking. Granted, this was from 2002 and Linus may no longer feel so strongly about the topic.

Show me a memory-intensive kernel in which Haskell runs close to the performance model. Sparse and dense matrix kernels would be a good place to start. Our C code for sparse matrix-vector products and sparse triangular solves gets better than 90% of STREAM bandwidth (based on an assumption of optimal cache reuse, STREAM is about 85% of hardware peak). Dense matrix kernels should get better than 90% of FPU peak. Unlik…

Let's be fair here. Numerical processing is not representative of most applications, but I concede the point.

It's an interesting question though. I'm a Haskell beginner, but I'm pretty experienced with Scala. Let me try to see how using sliding compares with a tight Java loop on statically allocated data for convolutions/filters.

Re: Linus Torvalds on Garbage Collection (2002)

#95

Earlier quoted context omitted.

The drawback with multiple processes is that they each have all the compiled bytecode on their heap. When I "import nltk" my heap goes from ~12 to ~36 MB. Add a few more dependencies and you end up wasting a non-trivial amount of RAM on python heaps.

You could do the import and then fork the child processes. That should share all the memory used by the nitk module between all the children (for as long as the memory is not modified by anyone, which triggers a copy-on-write allocation of the affected pages).

most forks do copy-on-write and every access to a python object meddles with reference count, which is - you guessed it - a write.

Re: Linus Torvalds on Garbage Collection (2002)

#96
post #48

Earlier quoted context omitted.

That's correct, unless the object is autoreleased, in which case the system will get around to deallocating it after the current run loop iterates (provided you're using the default autorelease pool).

Thank you, that makes sense. So, if I understand this correctly: if one wanted to take advantage of an opportunity to do some cache-friendly reallocation, then avoiding autorelease pools would be necessary.

That's rarely a realistic option if you use any Cocoa library code. autorelease is a pretty fundamental aspect of the Cocoa design.

Re: Linus Torvalds on Garbage Collection (2002)

#97
post #37

Shortly before Linus wrote this article in 2002, I wrote an XML-RPC library in C that used reference counting. By the time I was done, I'd written 7,000+ lines of extremely paranoid C code, and probably eliminated all the memory leaks. The project cost my client ~$5K. The standard Python xmlrpc library was less than 800 lines of code, and it was probably written in a day or two. Was my library about 50 times faster?…

I Guess Linus also made another suggestion which he didn't pursue on this paragraph: Generational garabage collectors tend to never re-use hot objects, and often do the copying between generations making things even worse on the cache The suggestion? Just reuse hot objects. Note, this post is from 2002. Garbage collectors have improved a lot over the last 9 years. Don't evaluate new technology with such old arguments…

Linus was quite specific about his problems with GCs. Just saying that "garbage collectors have improved" without specifics, and calling his arguments "old" doesn't add much information.

Can you tell us how they have improved in ways that address Linus's specific concerns? And explain how a generational garbage collector can effectively re-use freshly freed objects before they leave the cache? Which 2011 generational GCs take advantage of that idea?

Re: Linus Torvalds on Garbage Collection (2002)

#98
I'm very suspicious of anyone (even Linus) claiming that gcc is slow because of its memory management. The codebase is crufty and convoluted--- it's probably slow for a thousand different reasons. If you refactored into a clean design and rewrote the beast in OCaml (or any other language with a snappy generational collector), you'd probably get a large performance boost.

Re: Linus Torvalds on Garbage Collection (2002)

#99
post #95

Earlier quoted context omitted.

You could do the import and then fork the child processes. That should share all the memory used by the nitk module between all the children (for as long as the memory is not modified by anyone, which triggers a copy-on-write allocation of the affected pages).

most forks do copy-on-write and every access to a python object meddles with reference count, which is - you guessed it - a write.

The context of the copy-on-write win was the bytecode for modules. I don't know that you'd have anybody meddling with the reference counts for that...but I haven't really looked.
Post reply on HN