Graphics Performance in OS X Lion: The Effect of Model Selection in SMBIOS.plist

A while back, I lamented some graphics issues I experienced in OS X Lion.  I didn’t have any hard evidence to support my claim, but my EVGA NVIDIA GTS 250 (512mb) card choked in OS X Lion after purring along seamlessly in Snow Leopard.  I don’t require ungodly amounts of graphics processing horsepower, as reflected by my mid-range graphics card, but I play a few games.  Not only were my KOTOR frame rates unacceptably low, but simple transition animations within OS X lagged badly.

Following the introduction of the OpenCL framework to OS X, and even more pointedly, the retirement of the PowerPC architecture, gone are the days of XBench providing reliable graphics-inclusive benchmarking for your hackintosh.  Geekbench is a great tool for measuring CPU and RAM performance, but it falls short of providing discrete graphics benchmarking scores.  Enter Cinebench, a cross-platform benchmarking utility that also happens to be free.

A reliable benchmark should compare graphics performance in OS X Lion to that of the same card in Windows, a far-away, glass-windowed land in which NVIDIA provides updated graphics drivers on a continuous basis.  Before running the tests, let’s take a look at what Windows 7 says about my graphics card:

NVIDIA GTS 250 Specs
Page 1 of the specs for my graphics card, per the NVIDIA control panel in Windows 7.
GTS 250 Specs (Continued)
Page 2 of the specs for my graphics card, per the NVIDIA control panel in Windows 7.

My machine is admittedly old, but she still gets a 5.9 (out of a total 7.9) Windows Experience Index:

Windows Experience Index
The Windows Experience Index for my hackintosh, whilst I briefly cheat on OS X Lion with Windows 7...

Let’s get to the meat:  here are the results of running a GPU-only Cinebench test on my EVGA NVIDIA GTS 250 (512mb) card in Windows 7 Professional SP1 (64-bit): 33.78 fps

Results of Cinebench OpenGL test in Windows 7 Professional SP1 (64-bit)
Results of Cinebench OpenGL test in Windows 7 Professional SP1 (64-bit)-- my machine is in orange, sandwiched between some other benchmarks for comparison purposes.

What did the same test, run on the same hardware, produce in OS X?

Cinebench Results - OS X Lion 10.7.3
Results of Cinebench OpenGL test in OS X Lion 10.7.3-- my machine is in orange.

The Cinebench test run in OS X Lion 10.7.3 produced a whopping 8.02 fps, compared to 33.78 fps in Windows 7 Professional SP1.  This means that the card was performing 421% better in Windows than in OS X– all the hard evidence I needed to back up my theory that my card was sputtering in Mac OS.  Note:  You’ll notice that I removed the #6-ranked benchmark from this screenshot; it contains the result of my final test (you can find it below).

When I first noticed the performance decrease, I had read that some users who had selected a MacPro4,1 or MacPro5,1 model number in SMBIOS.plist were experiencing similar graphics issues.  Some hackintoshers even created custom entries in the AppleGraphicsPowerManagement.kext internal plist file because the power management stepping doesn’t work OOB for NVIDIA cards.

Below is the SMBIOS.plist file I was stashing in /Extra; you will notice that because my machine most resembled an iMac, I was using the iMac11,3 identifier:

<!--?xml version="1.0" encoding="UTF-8"?-->

 Copyright
 SMBios by 7ender @ InMac.org Created with Champlist.app
 SMbiosvendor
 Apple Inc.
 SMbiosversion
 IM112.88Z.0057.B00.1005031455
 SMboardproduct
 Mac-F2238BAE
 SMfamily
 iMac
 SMproductname
 iMac11,3
 SMserial
 XA94601LDWZ

By my understanding, OS X dynamically chooses which set of graphics d rivers to load at boot time based on the model of Mac specified in SMBIOS.plist, rather than analyzing the graphics processing hardware itself.  This is a bit of a programmatic shortcut, but it’s one that Apple can afford to take; Mac models and their corresponding GPUs are hard-coded and, theoretically, shouldn’t change following production of the computer.

The exception, of course, is the Mac Pro– users have long been able to upgrade the graphics card in the built-to-order Mac Pro, which means that OS X must boot more dynamically with regards to loading graphics drivers as long as SMBIOS.plist indicates that the machine is a Mac Pro.  As such, rather than deleting or modifying AppleGraphicsPowerManagement.kext to reflect my graphics card’s unique stepping, I wondered if simply modifying SMBIOS.plist to reflect a Mac Pro model rather than an iMac would force OS X to load a more dynamic set of graphics drivers at boot time.

My modified SMBIOS.plist follows below; note that the SMSerial value must also change to accommodate the modified SMProductName value:

<!--?xml version="1.0" encoding="UTF-8"?-->

 Copyright
 SMBios by 7ender @ InMac.org Created with Champlist.app
 SMbiosvendor
 Apple Inc.
 SMbiosversion
 MP31.88Z.006C.B05.0802291410
 SMboardproduct
 Mac-F42C88C8
 SMfamily
 Mac Pro
 SMproductname
 MacPro3,1
 SMserial
 G8819IY0XYK

I restarted, then ran Cinebench once more:

Cinebench - OS X Lion - Mac Pro SMBIOS.plist
The two scores in orange represent the tests run with the Mac Pro and iMac SMBIOS.plist configurations, respectively.

It’s not quite the 33.78 fps result that I was able to get in Windows, but the improvement from 8.02fps to 26.29fps indicates that I’m headed in the right direction here.

TL;DR: Modifying my SMBIOS.plist to reflect a Mac Pro (3,1) model rather than an iMac (11,3) improved the performance of my EVGA NVIDIA GTS 250 (512mb) graphics card by nearly 328%.

Note: I tried using the MacPro4,1 and MacPro5,1 models as well in order to test if I experienced the same performance drop-offs indicated in the aforementioned TonyMac86 post, but Lion refused to boot with either and I didn’t have the time or energy to figure out why.

The card still performs 22% worse in OS X than it does in Windows; I will need to investigate whether or not I can squeeze some more performance out of her by manually modifying the thresholds in AppleGraphicsPowerManagement.kext.  Until then, though, I’m just happy that Lion’s GUI is running smoothly, and I can once more focus on becoming a Jedi.  Now, if you encounter a similar systems malfunction in OS X Lion, don’t worry– you know a few maneuvers.

10.7.2 Update, or “Who turned out the lights?”

I updated my hack to 10.7.2 today and watched her boot up to a black screen. More accurately, the monitor went to sleep immediately upon loading the OS X GUI.

The interwebs indicated that the EFI string I’m using to inject my NVIDIA GTS 250 graphics card was causing the problem.

Sure enough, I removed the EFI string and was able to boot into the GUI, albeit without graphics acceleration.

I was able to add pseudo-acceleration by adding the Chameleon key to my com.apple.boot.plist, but it was choppy and slow.

Finally, I returned to my old way of graphics injection by throwing the NVEnabler.kext (64-bit) into /System/Library/Extensions (the NVEnabler devs claim that it should work in /Extra/Extensions as well, but I tried that first and it didn’t work).

TL;DR: To get my NVIDIA GTS 250 graphics card to play nice with OS X Lion 10.7.2, I had to remove the EFI injection strings from com.apple.boot.plist, remove the GraphicsEnabler plist key, and add NVEnabler.kext (64-bit) to /S/L/E.

Preparing Lion to Boot Quickly: Create an Extensions.mkext

EDIT 10/18/2011:  This doesn’t seem to be working with 10.7.2 (causes a kernel panic on boot).  Also tried adding <UseKernelCache><Yes> to org.chameleon.boot.plist (Chameleon 2.1 build 1627) and got a different KP.  More updates to follow.

Update: Fix is below in red.

– – –

I’m done with the real-life Lion metaphors after this.  Promise.  If only Apple would quit infusing interface metaphors into every other application it releases.

In other news, my Lion hackintosh never seems quite ready to boot.

It's like the folks at Apple had never even heard Scar's famous song. Isn't Steve Jobs on Disney's Board of Directors?

The Problem

Lion boots sloooooooooooooooowly.  Verbose output from the boot log indicates that Lion is processing every single kernel extension prior to booting (as if the -f flag was used), rather than caching the kernel extensions in a .mkext kernel extension boot cache.  TL;DR: Lion isn’t caching kernel extensions.

The Solution

It’s simple, really: force Lion to rebuild the kextcache and use it to boot.  The solution thread on InsanelyMac.com (one of many like it) contains a good explanation of what’s actually happening, but here’s the code to build the cache (Edit: to make OS X also build a cache for your /Extra/Extensions folder, add “/Extra/Extensions” to the code below):


sudo kextcache -v 1 -a i386 -a x86_64 -m /System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext /System/Library/Extensions

This *should* accomplish the same thing as setting the “kernelcache = yes” flag in com.apple.boot.plist.  What does setting this flag do? tonymacx86.com has a very straightforward answer here.  Please note that many a contributor to the InsanelyMac.com forum has reported kernel panics resulting from using this flag, while others have reported Lion booting fine (and quickly) but ignoring the kernel extensions placed in the /Extra/Extensions directory.

I have ONLY created the Extensions.mkext using the terminal code above; I HAVE NOT added the “kernelcache = yes” flag to com.apple.boot.plist.

The result?  My machine now boots in seconds instead of minutes.  That simple.

The Big Picture

What confuses me more than the problem itself (the solution is rather trivial) is why Apple decided to not include kernel extension caching automatically in Lion.  OS X can clearly still read the kextcache– so why doesn’t it write one?

I’m not entirely sure, but it may be hackintosh-specific.  I’m in the process of upgrading my brother’s MacBook Pro at the moment, so I will boot it with verbose logging and check back with the results.

Until then, enjoy the weekend!  And don’t spend your whole weekend playing with your hackintosh… It’s beautiful outside.      🙂