We build Firefox a lot[1]. We build every time someone pushes to try. We build every time someone pushes to mozilla-central, a project branch or an integration branch. We build every night on many branches. We build every time we want to ship an update.
Each of those builds is done on Windows, Linux, Mac OS and Android. In the most simple sense, the time it takes to get results from any of these platforms is comprised of:
- Time from push to build start
- Time from build start to build completion
- Time from build completion to test start
- Time from test start to test completion
What I am looking at here is the time from build start to build completion for Mac OS builds. The overall end-to-end time is the time from push to the last test completion. Currently, our Mac OS builds are by far the slowest. If we are able to speed up the mac build times, we should see improvements in overall end-to-end times.
We also want to have release builds to be as fast as possible. During a release, every minute we can save in the build is a minute more we can spend qualifying the product. During a chemspill release, every minute saved in the build is a minute sooner that we can protect our users.
For a multitude of reasons, we currently have some pretty slow Mac build hardware. We are building on 5 year old 1.83Ghz Mac Minis [2]. It’s definitely time to upgrade.
I have evaluated the build times of four different specs of Mac Mini that are available today. Because these machines only run 10.7, we can’t start using them straight away. We need to figure out how to build 10.5 compatible builds on 10.7 before we are able to use this hardware.
The specifications are:
- Mac Mini 5,3 – Quad i7 2.0GHz with 256GB SSD and 8GB ram
- Mac Mini 5,2 – Dual i7 2.7GHz with 256GB SSD and 8GB ram
- Mac Mini 5,2 – Dual i7 2.7GHz with 750GB 7200rpm and 8GB ram
- Mac Mini 5,1 – Dual i5 2.3GHz with 500GB 5400rpm and 8GB ram
Both the Quad i7 and Dual i5 have Intel Integrated as their only video chip, whereas both Dual i7 machines have a Radeon 6630M. This shouldn’t make any difference to building Firefox, but I do want to note this as a difference.
Because I don’t have access to actual pricing, I am unable to do a complete and accurate analysis of cost. All of my information uses wall clock timing and are scratch builds without rebooting. Since we have a limited number of configuration options, we have to figure out which configuration is best for us, not how to pick each component for maximum performance.
Value of solid state disks
One of the biggest decisions we need to make is whether to buy solid state drives or magnetic platter hard drives. There are a lot of things that factor into this decision. Having a faster disk means faster I/O. I did this test using Dual Core machines, because that’s what was available to me.
As shown in the graph above, the total time saved on a Dual i7 2.7GHz machine is just over 8 minutes, an 11% improvement. With Quad i7s it is more likely that we become I/O starved. It might be worthwhile to test a Quad i7 with a magnetic disk to see if we get a larger improvement there.
Interestingly, the portions of the build that take the least amount of time overall show the biggest improvement from using an SSD. Nothing at all is slower on SSD than on magnetic disk. I have another graph which shows this information as percentage of reduction here.
Parallelism in the build system
One of the main things we want to learn from this experiment is whether to buy dual or quad core machines. One major way we exploit parallelism in the build system is through the use of GNU Make’s -j option. In order to figure out which -j setting to use for the evaluation builds, I tested each machine using -j2, -j4, -j8, -j12 and -j16. The following graph is a plot of the build time against the -j setting used for each specification we are evaluating.
The best setting for the Quad-i7 is -j12 and the best setting for all dual core chips is -j4. The advantage of -j12 over -j8 for the Quad-i7 is less than one minute. This graph shows that for the compile step, the Quad-i7 is always the fastest and the Dual-i5 is always the slowest. Each machine exhibited roughly the same trend of dropping significantly until an ideal setting was reached. Any setting above the ideal setting caused times to increase. I did find that it is better to set the -j setting too high than it is to set it too low.
Interestingly, as the -j setting increases, the time advantage the Dual-i7 machine with SSD has over the otherwise identical machine with 7200rpm harddrive increases. This suggests that as we increase parallelism in the build system, we will need faster I/O to supply the processors with data.
Comparing to existing hardware
It is also worth comparing each of the machine specifications at their optimal -j setting to what we have now. The data source for the existing hardware is our Buildbot Status DB. I am using a nearly identical mozconfig file to our nightly builds to make this comparison valid. The only settings changed were the make -j flag and a couple of Mac OS target settings to allow me to build on 10.7. The builds on the old hardware are also done on 10.6 instead of 10.7, so this is not an exact comparison.
There isn’t an easy way to map all of the steps that my test builds do to the steps that our production builds do, so I selected the two longest steps of every Mac OS build.
This graph shows the absolute times for each specification. You’ll notice that the symbols generation is slower on the Quad-i7 than on either Dual-i7 machine. Symbol generation is not a parallelized process, which explains why higher clock rate dual core machines are faster than the quad core. Symbols is a much smaller portion of the overall build time than the build.
It is clear that no matter what we do, new hardware is a giant step in the right direction. The question is by how much we want to improve the situation.
This graph shows the time it takes each of the new machine specs to build and generate symbols as a percentage of time on the current machines. The Quad-i7 is clearly the fastest of the new machine configurations.
Cost
While I don’t know what our actual pricing might be, I do know what each of these configurations costs retail. Below is a graph of how much each minute of time saved from the compile step costs. In case we get discounts, I have included the costs adjusted for 5%, 10% and 15% discounts.
The order of absolute number of minutes saved is Quad-i7, Dual-i7-SSD, Dual-i7-HD then Dual-i5-HD. This graph does not take into account the cost of racking, networking, powering and cooling. It also doesn’t take into account the throughput advantages of fast machines or wait time improvements of many slow machines. This is for one single build, not counting any wait time.
Conclusions
The information above shows that the Quad Core i7 is faster than the all the dual core machines. I think we should buy the Quad i7 with SSD, as evaluated. We have work underway to improve the parallelism in the build system, which favours buying quad core. The quad core is also the overall fastest machine by 10 to 20 minutes. If we decide not to get the quad core, I think we should get the Dual i7 2.7GHz machine with a 7200rpm hard drive as the SSD adds significant cost in this configuration for minimal performance gain on dual core machines.
If you are a developer and understand Mac OS and want faster build times, please help fix bug 715397 so we can start making use of whatever faster build machines we end up buying.
Further Tests
There are a couple other tests that I think would give us useful information. I don’t have time to test these right now, but I am interested in the results
- Using a Mac Pro and DistCC to optimize compile times
- Use a mix of SSD and HD for OS, repo and objdir
- 16GB of memory in quad core minis
- quad core minis with hard drives
- effects on incremental builds
Code and data available on GitHub.
[1] Yesterday, we built it nearly 2400 times
[2] http://support.apple.com/kb/sp7 + ram upgrade