News for hackers. Stuff that matters.
Re:Apple Silicon M1: Black Magic Fuckery by rowls66 on Tuesday November 24, 2020 @09:05PM (#25205218)
The bit about reference counting being the reason that Macs and iOS devices get better performance with less ram makes no sense. As a memory management strategy, reference counting will always use more ram because a reference count must be stored with every object in the system. Storing all of those reference counts requires memory.

A reference counting strategy would be more efficient in processor utilization compared to garbage collection as it does not need to perform processor intensive sweeps through memory identifying unreferenced objects. So reference counting trades memory for processor cycles.

It is not true that garbage collection requires more ram to achieve equivalent performance. It is in fact the opposite. For programs with identical object allocations, a GC based system would require less memory, but would burn more CPU cycles.

Re:Apple Silicon M1: Black Magic Fuckery by Someone on Tuesday November 24, 2020 @09:21PM (#25205311)
“A reference counting strategy would be more efficient in processor utilization compared to garbage collection as it does not need to perform processor intensive sweeps through memory identifying unreferenced objects. So reference counting trades memory for processor cycles.”

I think it’s the reverse.

Firstly, garbage collection (GC) doesn’t identify unreferenced objects, it identifies referenced objects (GC doesn’t collect garbage). That’s not just phrasing things differently, as it means that the amount of garbage isn’t a big factor in the time spent in garbage collection. That’s what makes GC (relatively) competitive, execution-time wise. However, it isn’t competitive in memory usage. There, consensus is that you need more memory for the same performance (https://people.cs.umass.edu/~emery/pubs/gcvsmalloc.pdf: with five times as much memory, an Appel-style generational collector with a non-copying mature space matches the performance of reachability-based explicit memory management. With only three times as much memory, the collector runs on average 17% slower than explicit memory management)

(That also explains why iPhones can do with so much less memory than phones running Android)

Secondly, the textbook implementation of reference counting (RC) in a multi-processor system is inefficient because modifying reference counts requires expensive atomic instructions.

Swift programs spend about 40% of their time modifying reference counts (http://iacoma.cs.uiuc.edu/iacoma-papers/pact18.pdf)

So, reference counting gets better memory usage at the price of more atomic operations = less speed.

That last PDF describes a technique that doubles the speed of RC operations, decreasing that overhead to about 20-25%.

It wouldn’t surprise me if these new ARM macs use a similar technique to speed up RC operations.

It might also help that the memory model of ARM is weaker than that of x64, but I’m not sure that’s much of an advantage for keeping reference counts in sync across cores.

Re:Apple Silicon M1: Black Magic Fuckery by Shish2k on Tuesday November 24, 2020 @09:45PM (#25205481)
> reference counting will always use more ram because a reference count must be stored

True, reference counting stores references… but garbage collection stores garbage, which is typically bigger than references :)

(Unless you’re thinking of a language where the GC gets run after every instruction - but I’m not aware of any that do that, all the ones I know of run periodically which gives garbage time to build up)

Re:Apple Silicon M1: Black Magic Fuckery by socialdemocrat on Tuesday November 24, 2020 @09:24PM (#25205331)
No, many garbage collection approaches WILL require more RAM, some need twice as much RAM to run efficiently. Then there is the case that with garbage collection can have a delay which lets garbage pile up thus using more memory than necessary. Retain-release used by Apple is not as efficient, but you reclaim memory faster. https://www.quora.com/Why-does-Garbage-Collection-take-a-lot...
Re:Apple Silicon M1: Black Magic Fuckery by jandrese on Tuesday November 24, 2020 @09:13PM (#25205259)
I think it's more a design pattern you see more with GC collected languages where people instantiate objects with pretty much every action and then let the the GC handle the mess afterward. Every function call involves first creating a parameters object, populating it, then forgetting about it immediately afterward.

I've seen this with java where the memory usage graph looks like a sawtooth, with 100s of MB being allocated and then freed up a couple of seconds later.

Re:Apple Silicon M1: Black Magic Fuckery by jhgb on Wednesday November 25, 2020 @03:18AM (#25207014)
Isn't it the case with Java that it will do this because you do have the memory to spend on it? Generally this "handling the mess afterward" involves some kind of nursery or early generation these days, but their size may be use-case-dependent. If tuned for a 8/16 GB environment, presumably the "sawtooth" wouldn't need to be as tall.
Re:Apple Silicon M1: Black Magic Fuckery by notriddle on Wednesday November 25, 2020 @10:22AM (#25210123)
Yes, but the reason it does it is to make it fast. The shorter your sawtooth spokes, the slower your app.
Re:Apple Silicon M1: Black Magic Fuckery by jhgb on Wednesday November 25, 2020 @02:24PM (#25213155)
Slower in what metrics? Latency? Throughput? Not to mention that the behavior may strongly depend on the GC design and the HW platform in question. It seems far too difficult to make a blanket statement about what is and isn't achievable in a specific use case.
Re:Apple Silicon M1: Black Magic Fuckery by cesarb on Wednesday November 25, 2020 @06:12AM (#25208026)
> reference counting will always use more ram because a reference count must be stored with every object in the system

In the tracing GCs I have seen, an "object header" must be stored with every object in the system; the GC needs it to know which parts of the object are references which should be traced. So while reference counting needs extra space to store the reference count, tracing GC needs extra space to store the object header.