All Work and No Play Makes a Quiet MacBook Pro
March 13th, 2006I’m the (mostly) happy owner of a MacBook Pro (MBP). Like every other MBP owner, I’m excited and happy to have at my portable fingertips unprecedented Mac computing power. Also like every other owner, I’m slowly going insane from the now infamous “hissing/whining” processor noise.
As annoying as this noise is, it’s nothing new to me. I suffered a nearly identical noise on my Dual PowerMac G5, until I discovered through the folk wisdom of the Internet that “disabling CPU napping” would alleviate the problem. Ah – sweet silence! Since that day, I have been flagrantly wasting CPU energy on my Mac by way of the “disable napping” script that runs every time the computer boots. The script relies on extra software provided by Apple’s CHUD tools, and on the rare occasion when my computer has ended up temporarily without those tools, I’ve noticed almost immediately that my brain was once again being bored into by little audio termites.
The problem on the MacBook Pro is generating a lot of discussion on the web. I think it’s worse now because the laptop sits closer to and relatively level to your ears, while the G5 tower often rests somewhere around the corner of your desk and closer to the floor. Annoying whine from an Apple product? No problem, I’ll just pull the ol’ “disable napping” trick. Ha ha! I’m so good at this. What? The Pentium M doesn’t support napping? Sure enough, typing the magical “hwprefs cpu_nap=false” command at the command line returns the very unhelpful “nap not supported by this processor type.”
Over the past few weeks, a number of data points have emerged on the web about what may or may not cause the hissing noise, and what may or may not quell it. Among the most prominent is the observation that “using the built-in iSight” causes the noise to disappear. I tried this the way most people try it, by launching the bundled Photo Booth program. Sure enough. No more noise. But how could that be? I had a hard time believing that there was some magical link between the video circuitry and the “annoying noise” circuitry.
Spotting a link to discussions about the problem in Rentzsch‘s del.icio.us feed, I was reminded to look into the problem more carefully. Personally, though running the Photo Booth application does quiet the noise, it’s not something I feel comfortable doing with my extremely powerful, top-of-the-line Mac notebook!
I sat down at my MBP, intent on getting to the bottom of the problem. I planned to try different things and see what made the noise change or go away. But what’s this? No noise? Try as I might, I couldn’t get irritation to occur. Aha, I noticed at last. I’m plugged in. With the MBP plugged in and charging, apparently the computer doesn’t produce the noise. I was becoming more and more convinced that the problem lay in the CPUs. I disconnected the extremely cool magnetic power connector, and the noises immediately started occurring. If it’s a CPU issue, then perhaps disabling one of the cores will alleviate the problem. Yes, on my machine it certainly did. This is all consistent with the Dual G5 noise problem: when the lazy core has nothing to do, it makes a whining “I’m bored” noise.
It make sense that a video-intensive program like Photo Booth would alleviate the problem. Not because it’s using the built-in iSight, but because it’s furiously processing video data and undoubtedly making the most of that dual-core Pentium chip. Fine – but that means if I’m running Photo Booth I’m taking power away from other programs, like my compiler, that could really make better use of it. Also – the green glow of the iSight camera’s activity LED doesn’t exactly fade into the background. Isn’t there some other program that could keep the CPU just busy enough to stay quiet?
I’m not sure if there is such a program, so I made my own. It turns out that writing an extremely asinine program designed to spin the CPU endlessly does silence the problem. My program simply loops forever comparing the same byte of a string to a character value which it will never be. Pretty stupid, huh? At first I just let it take over the whole CPU, to confirm that the noise would stop, but then I got curious about how much I could yield and still keep the computer quiet. During my experiments, I added a call to usleep() and played with different settings to see at what threshold the noise would come back. In my extremely unscientific tests, the tool has to use around 8% of the (a?) CPU to keep the noise from happening. Arranging for less aggressive use of the CPU resulted in variations on the hissing noise’s rhythm and perceived pitch. I am willing to part with 8% of the CPU if I must, but is there a better way?
I remembered that this is UNIX, and one nice thing about UNIX is the “nice” function call, which sets your priority either lower or higher than the “standard priority.” Apparently nice() has been obsoleted by a newer “setpriority()” call, so if you want your code to be correct you should use that instead. I like using nice() because this is a hack, it works, and I like the way it sounds. Here is my complete “dumbcpu” command-line tool, which should silence your MBP:
main()
{
char* dummy = "blastedPentiumM";
// Give this process the lowest possible priority
(void) nice(20);
// "Use" that CPU
while (dummy[0] != 'l')
{
// Give the CPU a rest. Use a lower value if it's still noisy.
usleep(100);
}
}
For my less programming-minded readers, this is the source code to a complete command line tool that, when compiled, can be run from the Terminal application. If you’re not up for all that, just download the compiled binary, which also includes the source file. [Update: Check out the 1.1 version here, sorry no source for this one]. You should also be able to add the compiled binary to your “Login Items” in order to have the tool run (and your noise silenced) every time you log in to your account. (Update: This wasn’t true at first, but is now that I have changed the binary distribution to a simple application instead of a command-line tool).
How important is it to run this command-line tool instead of Photo Booth? To confirm my suspicions that running Photo Booth was robbing me of valuable processing time, I picked the closest project at hand and timed a clean build of it from the command line with xcodebuild. On my 1GB RAM MBP running full-bore, with annoying whining noises and all it takes almost 8 seconds exactly to complete this build from start to finish. Next I launched Photo Booth and ran the test again. This time it took almost 9 seconds. So Photo Booth is robbing me of 1 out of every 9 seconds. Unacceptable.
Running the above-linked tool quiets my MacBook Pro, yet allows compiles and any other ordinary tasks that want to harness my MBP’s power to complete at full-speed. Observing the behavior of all involved tasks with the “top” command line tool, it’s easy to see how the “dumbcpu” tool drops to nearly 0% CPU use when other, more important tasks are being run.
Does this problem suck? Yes. Does it need to be addressed by Apple before the world goes insane from humming/hissing disease? Yes. Does this little tool work around the problem in a more acceptable way than any other proposal I’ve seen? I humbly suggest that it does.
Update: Smart people like Kevin Ballard and Chris Liscio quickly observed that this tool takes up 100% of the CPU when the machine is idling, which sort of sucks. So to alleviate this, I put back a usleep() call in the while loop. On my MBP usleep(100) seems to cause about an 8% CPU usage, which is still half of what Photo Booth takes, and keeps the CPU quiet. The downloadable binary has also been updated with this change. Thanks Kevin & Chris for pointing this out.
Update 2: I notice a noise still persists when I run the tool, though it’s much less noticeable. I think it’s the “sound of one chip napping” or whatever. I suppose that altering the tool so that it spawned a thread to keep both CPUs busy might seriously silence the MBP. I’ll leave that as an exercise for the concerned reader.