[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: apple's objc runtime on linux?

From: Dietmar Planitzer
Subject: Re: apple's objc runtime on linux?
Date: Sat, 8 Nov 2003 14:10:53 +0100

On Friday, November 7, 2003, at 11:06  PM, Benhur Stein wrote:

On 2003-11-07 12:57:06 -0200 Markus Hitter <address@hidden> wrote:

How about installing Darwin and do the comparison there? GNU runtime should compile out of the box there.
Well, it passed my mind, but I thought it would be too much work.

In fact, it is a curiosity I have, which runtime is faster, and why there always comes the idea of unifying runtimes in favor of the apple one. Is it really better, and in which aspect? One thing I heard (but it was a long time ago, when I got to know objc, maybe it is not like this anymore), was that one great advantage of gnu's runtime is that it is thread-safe without the need of locks, while next's behaved differently on multi-threaded
and single-threaded programs.

NeXT's runtime indeed required a lock in the messenger when support for multi-threading was originally added. However, things have changed since that. First of all, Apple's current runtime always operates in multi-threading mode (objc_setMultithreaded() is a NOP). Secondly, and more importantly, it also no longer takes any lock.

Apple's runtime achieves lock free multi-threading support by tacking advantage of some Mach APIs and by implementing a simple GC strategy. Namely, whenever a new entry is added to a class cache, the class cache is copied and the new entry is only added to the copy. The old cache is then atomically replaced with the copy (simple pointer replacement) and the old class cache is put on a garbage list. From time to time, the runtime checks whether some thread is still accessing one of the class caches on the garbage list. If so, its left intact. Otherwise the memory occupied by the class cache is freed up.

I took a rapid look at the message sending code of both runtimes and I really doubt that
apple's can be faster than gnu's.

Well, I really, if not extremely, doubt that GNU's runtime could be faster than Apple's on the _same_ hardware and OS. First and foremost, because Apple's messenger is written in hand optimized assembler.

Yes, I know that people say that modern compilers produce better code than a human being could. Now, reality is a harsh beast and I have yet to find a compiler for a RISC CPU which produces really good code. It doesn't take much to write assembler code which far outperforms i.e. C code compiled with gcc on PPC with optimization level O4. Its even much easier for C++...

Further, Apple has invested a lot of time and energy over the past years in order to profile the messenger code and to optimize it further and further. Today the messenger requires just 21 PPC instructions overall. The cache lookup loop code is just 8 instructions which fit exactly in a single cache line of the G3/G4 first level cache. Compare those 21 instructions to the 9 (PIC to PIC) instructions which are needed just to implement a Mach-O style function call stub and you should see that you'll have a very hard time achieving the same low number of instructions if the messenger would be written in C and the code would be produced by a compiler.

Another advantage of the handwritten assembler code is that it makes it easy to implement a daisy chain call sequence, where the method implementation is called with a simple bctr (jump) instruction. This makes it unnecessary to execute two full subroutine calls.

Some simple measurements I've made on gnu's runtime (time to do 1e9 calls
to an empty method/function):

19.5 normal method call
 6.8 indirect pointer (IMP)
 5.1 direct call to 2-arg function
 4.2 direct call to void function
 0.5 empty loop

I think its _very_ important to keep a few things in mind when comparing the GNU and Apple runtimes, in order to get meaningful results:

I) First and foremost, remember that Apple's messenger is de facto only optimized for PPC. This is the platform which is currently relevant to Apple. The x86 messenger has not seen as many optimizations over the past years.

II) Compare both runtimes on the same hardware platform and OS, only. I.e. comparing the GNU runtime running on Linux PPC to the Apple runtime on Darwin PPC is probably quite misleading, because Darwin uses Mach-O as its binary format and ABI while Linux uses ELF. Different ABIs lead to different function call performance.

III) Keep in mind that gcc's code generation quality on PPC is, well, limited. Although, it has been noticeably getting better in recent versions.

Anyway, regarding a merge of the Apple and GNU runtimes: I'm personally not a very big fan of this idea. One reason being that I don't really see what the gain would be for the Apple and the GNUstep community. Both the GNU and Apple runtime have already been developed and have, functionality-wise, not been changing that much over the past years. A merge would not necessarily result in any noticeable reduction of the maintenance burden for either side. However, there is the real danger of making things worse for at least one side. Be it a reduction in performance (which would absolutely not be acceptable for me and I assume anyone else) or the introduction of legal uncertainty. There is also the tendency that both sides are effectively moving in different directions and have seemingly different priorities. I.e. GC support in the GNU runtime vs. exceptions and synchronization support in the Apple runtime. A merged runtime would either try to be everything to everyone with the implied complexity and possible performance degradation, or one side would have to give up something.

I think that the more rewarding thing to do would be to unify the (core-) runtime APIs.

Regarding porting Apple's runtime to Linux: Apple's runtime currently depends on three Mac OS X specific APIs: CoreFoundation, Mach and dyld. The first problem can be solved by trying to get CF to compile on Linux. The latter two are, well, a problem :)


Dietmar Planitzer

reply via email to

[Prev in Thread] Current Thread [Next in Thread]