7 ms·
I don't quite understand how 'retain' and 'release' can be more memory efficient on Apple Silicon than x86.... I can understand how they can be more efficient f
by berkut 6y ago
I don't quite understand how 'retain' and 'release' can be more memory efficient on Apple Silicon than x86.... I can understand how they can be more efficient from a performance standpoint in terms of more efficient reference counting, but I don't understand how that translates to less memory usage which is apparently what's being argued... ?
Unless on x86 some of the 'free's when the ref counts hit 0 were being batched up and deferred, and that doesn't need to happen now?
- saagarjha 6y agoI believe it was being brought up as an example of "Apple has designed their hardware around their software" and then that translates to "Apple's software does well on machines with less memory".
- berkut 6y agoCompared to something like Android, sure, I get that, but compared to ObjectiveC/Swift on x86 (which I think was being argued - i.e. against the Intel Macs)? I guess it makes reference counting in general more efficient, I'm just saying I don't see why that would mean Apple Silicon Macs running ObjectC/Swift code would have less memory usage than the same code compiled and running on x86.
- saagarjha 6y agoI'm not necessarily convinced by the posted argument. That being said, I tend to think that people running a bunch of VMs and Electron apps and Docker cause them to use a bunch more RAM than I would consider to be "reasonable", and they've lost sight of how much you can do in a lesser amount of memory. (Typing this from a computer with 8 GB of RAM, which I have repeatedly been told is "below adequate" for development.)
- LaGrange 6y agoThe problem is, by now development practices in many companies effectively force using multiple large containers. I know an x stack could use 4x less memory if I spent considerable time on ripping out unnecessary cruft, but few people in the company would agree that it's time well spent, and the home office allowance suffices for a machine with 32-64Gb RAM (especially in 2020, when I don't really see that much value in laptops for dev work anymore).
- ianhowson 6y agoI don't think retain/release perf has anything to do with memory consumption, but I have seen a bunch of reviews claiming that 8GB is perfectly fine. This is fascinating to me, because: (a) every 8GB Mac I've used in the past has been unusably slow (b) since upgrading my 32GB Hackintosh to Big Sur, my usual 40GB working set is only about 20GB. (c) My 2015 16GB MBPr with Big Sur is also using about half as much physical memory on the same workload. Swappiness is up a little, but I haven't noticed. So my guess is that something in Big Sur has dramatically reduced memory consumption and that fix is being commingled with the M1 announce.
- jdminhbg 6y agoiPhones and iPads also have relatively small amounts of RAM compared to Android devices in the same class, so I wonder if Apple is doing something smart with offloading memory to fast SSD storage in a way that isn't noticeable to the user.
- saagarjha 6y agoNot on iOS.
- raphaelj 6y agoThis is most probably more linked to Java/Kotlin vs Objective-C/Swift. Want an array of 1000 objects in Java ? You'll endup with 1001 allocations and 1000 pointers.
- BillinghamJ 6y agoPretty sure you'll end up with exactly the same in an NSArray? ObjC is excellent but it's not doing anything fundamentally magic there
- dwaite 6y agoIn Swift you can add value types to the heap-backed array directly, in ObjC you can use stack allocated arrays (since you have all of C) and there are optimizations such as NSNumber using tagged pointers.
- trevyn 6y agoThey stuff the reference count in the unused bits of the 64-bit pointers.
- berkut 6y agoSo just tagged pointers essentially? That's possible on x86 isn't it (unless it's an endian-thing)?
- saagarjha 6y agoIt is and both both platforms use tagged pointers.
- j16sdiz 6y agoyes, but they have hardware acceleration for that specific tagged pointer type.
- wtallis 6y agox86-64 was designed to prevent (or at least discourage) efficient use of tagged pointers, with the higher half/lower half split in the virtual address space. All the excess high-order bits you don't need for actual addressing are required to have the same value, so you effectively only get at most one tag bit.
- saagarjha 6y agoThey’re required to have the same value upon dereference; there is no restrictions prior to this as assembly doesn’t care what a register is. The bits are appropriately masked off when necessary prior to using the pointer.
- CountSessine 6y agoYikes. That's the same shenanigans that got them into trouble with the 68000. Everyone stuffed data into the top 8 bits of pointers because even though the 68000 had 32-bit addressing registers, it only had a 24-bit address bus and the top 8 bits were dontcare's. Then, the 6802x came out with more address lines and... ...and that's basically why x86_64 was specified to require a particular bit pattern in high-order bits - it was to stop applications and OS programmers from writing a bunch of software with tagged pointers which would tie Intel's and AMD's hands when adding address lines. I guess Apple is ok with tying their own hands.
- deleted 6y ago[deleted]
- breatheoften 6y agoI think the argument they were trying to get to but totally failed to make is possibly along these lines huge memory bandwidth relative to ram size + os level memory compression => massive reduction in memory pressure for many many many workloads. macos has supported memory compression for awhile now -- i would hypothesize that M1 may have massively improved that subsystem in ways that actually do translate into needing less memory on average for a lot of common real-world workloads that amount to "human timescale multitasking" between large working sets -- eg i click this app and it has a huge working set and then click into another that has a large working set and then click back -- with those clicks that represent application context switches occurring very very rarely in machine time scale. If memory compression subsystem can swap working sets into and out of compressed memory space insanely quickly with low power usage then the os might've gotten very aggressive about using that feature to put not recently accessed memory into compressed memory space.
- deleted 6y ago[deleted]
- sedatk 6y agoReference counting releases memory as soon as it gets dereferenced, while GC cleans up memory periodically, which means higher memory usage (more than what's actually in use at any moment).
- cosmotic 6y agowith lots of tiny, short lived objects, reference counting can be hugely inefficient.
- dwaite 6y agoSystems that can reap no longer needed objects rather than walking them can help here. The automatic approach is a copy collector, which is typically the more often approach of a generational garbage collector. Since a copy collector typically works by following references, this also increases data locality for machines with a small amount of L1 cache. Garbage Collectors and JITs typically work best with hardware support, as you need to check pointer reads and writes as objects are being moved around or code is being rewritten. A lot of these systems use MMU gymnastics, such as mapping the same memory page into multiple locations with different permissions. You also have systems where you create the objects knowing that they will be tiny and short-lived with a fixed lifetime, which can be hugely efficient. This is how Apache Bucket brigades work, since they know that other than a few special cases all memory allocated while handling a request will be garbage once a response is returned.
- CyberDildonics 6y agoLots of tiny memory allocations are inefficient no matter what. Slight deallocation refinements to poorly made software (the reference counting part is not 'hugely inefficient') is focusing on the wrong thing.
- cosmotic 6y agoLots of tiny memory allocations is pretty efficient in java. The VM would have already allocated memory from the kernel so there's no context switch, and once the tiny objects are no longer referenced, deallocation is a free (0 machine instructions) side effect of garbage collection. Garbage collection isn't free, but it can be cheap(er) than reference counting millions of objects with explicit and individual allocation and deallocation.
- pritovido 6y agoIt is a simple process, everything that you do in a language needs to be mapped into lower level instructions. If the lower level hardware instruction does not exist, you use multiple of other instructions to emulate that. If you add a low level instruction that maps a very common high level operation in hardware, you don't need to call 5 to 10 software functions(extremely expensive),each calling lots of opcodes but just can execute a single opcode and works by hardware beings extremely faster. It is not hard to be better than Microsoft here. From my personal experience and having disassembled lots of their code they always were lazy bastards. They cared 0 about efficiency. Why should they? They had monopolies like Office or Windows giving them over 95% margins. They could just use the money they printed to buy everything instead of competing. Lisp machines did that (adding opcodes that map the high level language) with the most common Lisp operators. Those machines were extremely expensive, in the hundreds of thousands of dollars because few could afford that. Apple sells in massive scale, in the hundreds of millions of CPUs per year, making this cheap for them.
- lispm 6y ago> each calling lots of opcodes but just can execute a single opcode and works by hardware beings extremely faster. Typically these language oriented instructions need to be implemented by microcode in the CPU. Often this does not create a fast system, but it helps to keep the compiler simple. Examples are typical Lisp Machines, you've mentioned. With RISC CPUs OTOH the idea is to make the CPU instructions more primitive and put more effort into optimizing compilers instead. There were a few attempts to combine (high) language supporting architecture and the RISC principle, but I personally have never seen such a machine. > in the hundreds of thousands of dollars Usually in the 'tens of thousands of dollars'.
- dwaite 6y agoI believe the idea was that reference counting was more memory efficient than other forms of garbage collection, such as copy collectors and mark and sweep collectors which commonly make up generational garbage collectors. Languages like Java also do not yet support stack-allocated value types outside a few primitives like integers, and heap allocations are both slower and less space efficient due to the indirection and memory management.
- jhgb 6y agoYou do get stack-allocated value types in languages like Go or C#, though, so these shouldn't be subject to the same limitations that Java is.