[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: NSZone pointers
From: |
David Chisnall |
Subject: |
Re: NSZone pointers |
Date: |
Sat, 23 Jul 2011 10:42:40 +0100 |
On 23 Jul 2011, at 07:57, Richard Frith-Macdonald wrote:
> David, I've never liked zones, but we probably need to keep them around for
> people who *do* want them. I implemented per-object zone pointers simply
> because I couldn't figure out a way to get reasonable performance if people
> used a lot of zones and we had to look outside the object to determine the
> zone, but that was back when machines were slower (and when I thought people
> actually used zones a lot), and the world has changed in the last decade or
> so :-)
I think people DID use zones a lot - they just don't anymore.
> Even now, if we continue to support zones without zone pointers in objects,
> we will slow down a bit because we have to do some sort of check to see
> whether an object is in a zone or not, but I suspect that
> a. practically nobody uses zones
This seems to be the case. The only program I found that used zones was one I
wrote - and that was just a research prototype.
> b. the slowdown is relatively unimportant on modern hardware
If anything, I'd expect the reduced cache churn to have more of an impact.
-zone is called relatively infrequently over an object's lifetime, but we lose
a word of cache per object for the zone pointer. By the way, I did some
profiling a few years ago and found that the average size for Objective-C
objects (counting allocations - actually, in an NSZone) was 24 bytes (on a
32-bit system), so removing the zone pointer gives about a 15% memory saving in
object memory. In Gorm, it's about a 2% saving, because object memory is
dwarfed by things like images and mapped code.
> Why don't we make them a configurable default, but with the default setting
> being to NOT have them?
Well, as a first step, I can commit the NSObject.m part of my diff. This still
allows zones to work, but removes the pointer. We can then think about
removing them completely. I'm a bit hesitant to make that a configuration
option, because I suspect that will leave us with a code path that hardly
anyone uses, and which is therefore easy to break.
> If we build with zones turned off (the default), we could just optimise the
> NSZone... functions to be direct calls to the malloc family of functions, and
> code would be a tiny bit faster than at present.
>
> If we build with zones on, we could maintain a map from objects to zones and
> the -zone method could consult the map to see if an object is in a
> non-standard zone (or we could ask each zone if the object is in it), rather
> than keeping a pointer before the object. These lookups would make
> everything slower, but we'd then have a consistent memory layout for an
> object irrespective of the configuration option.
The diff I sent calls NSZoneForPointer() in -zone, which then asks each zone if
it owns the pointer. In the no-zones case, this function already has a fast
path that skips the lookup and just returns NSDefaultMallocZone(). If someone
is implementing a custom zone that doesn't use a contiguous block of memory
(allowing fast checks by just checking if the pointer is in the range), then
they need to implement a map or similar. The most common use for zones even in
the NeXT days was implementing short-lived bump-the-pointer allocators. These
can have a very fast lookup, and there generally weren't many of them alive at
once.
With GC, we do use two zones - one for the malloc zone and one for the GC zone
- but the GC code paths have their own NSZoneForPointer() that handles this, by
just asking the GC if it's managing the pointer. If we're going to remove
zones, then we need to make sure that we remember about this...
David
-- Sent from my IBM 1620