Author Archive

Knowing how much disk seeks hurt

We all know disk seeks hurt. But we usually don't have a precise idea how much. How about getting that idea?

Here is a little experiment I ran a few days ago. I took the output from the systemtap script tracking I/O I wrote, on a Firefox startup after boot. Each line of that output, which gives a timestamp (which we don't care about here), a file name, and an offset, represents a 4096 bytes read (one page).

The first set of data points I got is how much time it takes to reproduce this read pattern after a reboot, and how that compares to Firefox startup time. For what it's worth, I did group following reads, to avoid doing too many system calls, and also avoided kernel readahead by using direct I/O, meaning I would only read exactly what the kernel reads when Firefox normally starts.

All the following tests were done under the usual conditions (see previous posts), but I limited the tests to the x86-64 architecture, because all that really matters is the disk. I'll mention, however, that the amount of data read in these tests is 34,729,984 bytes, and that the original I/O pattern looks like this:

Zooming around the main location where most I/O happen, we can see the pattern is still bumpy:

This somehow looks familiar, doesn't it?

We already know for a fact that even these patterns that, on the whole disk, look like pretty much insignificant, have an important impact on startup time. Try to imagine what kind of difference could be observed if we were reordering all these reads.

Anyways, back to that I/O simulation, we first need to see how far it is from the actual Firefox startup. We would rather that simulated I/O + warm startup/hot cache end up close to the real thing. However, we need to keep in mind, as we saw in a previous post, that CPU scaling, when mixed with I/O, has an influence on startup time. Warm startup not involving I/O, the CPU can run at maximum speed the whole time. As such, for a fair comparison, we need to compare to cold startup time with the CPU forced at maximum speed, which we saw is faster than startup time with CPU scaling.

Average time (ms)
Simulated cold startup 2,764.26 ± 0.42%
Warm startup 250.74 ± 0.18%
Simulated cold + warm 3015
Real cold startup 3087.47 ± 0.31%
Difference 72.47 (2.35%)

Close enough, I'd say. The difference is most probably caused by metadata reads and a few other things, that isn't in the systemtap script scope.

Now we know our simulated I/O is close to reality, what happens if we reorder all these reads according to the position on disk?

Average time (ms) Corresponding transfer rate
Simulated I/O 2,764.26 ± 0.42% 12.56 MB/s
Reordered I/O 1,473.34 ± 0.43% 23.57 MB/s
Difference 1,290.92 (46.7%) n/a

That's almost twice as fast ! And the disk doesn't even have a big throughput (around 30MB/s). Let's see what it does with a disk with a bigger throughput (85MB/s).

Average time (ms) Corresponding transfer rate
Simulated I/O 1,898.66 ± 0.16% 18.29 MB/s
Reordered I/O 644.0 ± 0.15% 53.93 MB/s
Difference 1,254.66 (66.08%) n/a

That's almost three times as fast ! The faster the disk, the bigger the improvement we can get by reordering and grouping I/O, which is not unexpected, but here we can see how much having to go back and forth on the disk hurt badly. Obviously, the numbers from the faster disk can't be directly compared to the ones from the slower disk, because the data was not arranged the same way on the disk, and file system fragmentation, as well as how the file system is filled also have their own share to add to the problem.

And because it's more impressive to see on a graph than in a result table:

Disks seeks hurt. Badly.

2011-02-08 15:42:43+0900

p.d.o, p.m.o | 5 Comments »

Startup I/O: how do 3.6 and 4.0 compare?

During the past weeks, I've been posting a lot of data about what various changes can bring in terms of startup time improvement. It is now time to look back on how thing have changed between 3.6 and the upcoming 4.0.

With the same setup I've been using in the past, and the same modus operandi, with a fresh profile:

3.6.14pre 4.0b8 Difference
x86 2,933.46 ± 0.72% 3,228.76 ± 0.57% 295.30 (+10.06%)
x86-64 3,150.5 ± 0.59% 3,382.0 ± 0.51% 231.5 (+7.34%)

So, 4.0b8 ends up being slightly slower than the latest 3.6 on startup with a fresh profile. Now that relocation packing landed, we should be closer to 3.6, but still slightly slower.

On the other hand, 4.0 has seen two main changes directly impacting on startup time:

  • omni.jar: most chrome, preferences, javascript modules, and components are now all packed in a single file in the Firefox directory.
  • packed extensions: most extensions are not unpacked anymore in the profile directory,

Let's thus see how each of these is making a difference, starting with omni.jar:

4.0b8 without omni.jar 4.0b8 Difference
x86 3,420.4 ± 0.92% 3,228.76 ± 0.57% 191.64 (-5.60%)
x86-64 3,554.22 ± 0.82% 3,382.0 ± 0.51% 172.22 (-4.85%)

As can be seen here, packing most files in the Firefox directory did bring roughly a 5% speedup on cold startup, which helped keeping 4.0b8 somehow close to 3.6 in startup time on fresh profiles.

3.6.14pre with extensions 4.0b8 with extensions Difference
4,457.18 ± 1.79% 4,235.14 ± 0.60% 222.04 (-4.98%)

Taking six of the most popular extensions that work in both 3.6 and 4.0, we can see the positive effect of keeping extensions packed, especially considering a fresh profile is slower with 4.0. It has to be noted, though, that one of these extensions enforced being unpacked (which is still a possibility for extensions requiring it), so the 4.0 profile had effectively five packed extensions and another unpacked one.

2011-02-08 11:49:33+0900

p.m.o | 9 Comments »

Yet another clarification about Iceweasel

I'm glad that 5 years after the facts, people are still not getting them straight.

The Firefox logo was not under a free copyright license. Therefore, Debian was using the Firefox name with the "earth" logo (without the fox), which was and still is under a free copyright license. Then Mozilla didn't want the Firefox name associated to an icon that is not the Firefox icon, for trademark reasons. Fair enough.

Although at the time Debian had concerns with the trademark policy, there was no point arguing over it, since Debian was not going to use the logo under a non-free copyright license anyway.

Now, it happens that the logo has turned to a free copyright license. Request for a trademark license was filed a few weeks after we found out about the good news, and we are still waiting for an agreement draft from Mozilla to hopefully go forward.

It is still not certain that this will actually lead to Debian shipping something called Firefox some day, but things are progressing, even if at a rather slow pace, and I have good hope (discussions are promising).

By the way, thank you for the nice words, Daniel.

2011-02-07 20:42:47+0900

firefox, p.m.o | 7 Comments »

Backwards I/O vs. Forward I/O

I mentioned it in the past, and so did Taras, static initializers are currently called in reverse order of their location in a library. This can be seen, for example, in the various graphs I gathered about startup I/O. I also mentioned that I had written a small tool reversing these static initializers in ELF binaries. I however hadn't checked the impact on startup. Until today.

The testing setup still remains the same as in previous posts and the results are still the average and 95% confidence interval for 50 startups of an unmodified Firefox 4.0b8 build.

With backwards static initializers (ms) With forward static initializers (ms) Difference
x86 3,228.76 ± 0.57% 2,888.44 ± 0.55% 340.32 (10.5%)
x86-64 3,382.0 ± 0.51% 3,102.46 ± 0.51% 279.54 (8.26%)

I'm actually surprised by the result. I did expect that forward reads would be slightly faster than backwards reads, I wasn't expecting that much difference.

I guess I should work on bug 606137, then. Combined with relocations packing that landed after beta 10, it should have a nice startup impact.

2011-02-01 17:45:23+0900

p.m.o | No Comments »

Effect of packing relocations revisited

A couple weeks ago, I was checking how packing relocations affected startup time. Now that we have some additional information about startup, it is time to revisit the startup times with relocations packing, and more precisely, how the time spent before XRE_main is affected.

This time I didn't bother to collect 50 startup times to get more accurate figures, mostly because as of writing, I don't have scripts to gather these data automatically (especially on mobile devices).

Platform time spent before XRE_main without relocations packing (ms) with relocations packing (ms)
GNU/Linux x86 1,362 1,273
GNU/Linux x86-64 1,643 1,318
Maemo 5, n900 1,717 1,427
Android 2.2, HTC Desire 4,250 3,568

All the numbers above were taken after a fresh boot with a more or less recent nightly (n900 was from a week ago, others are from today). The Android number with relocations packing was gotten from a build where it miraculously started without crashing (relocations packing apparently unveils a dynamic linker problem) ; it might be wrong.

2011-01-24 19:10:46+0900

p.m.o | No Comments »

Little extension to expose startup time

A few days ago, Taras landed a new API to gather startup timings for a few events occurring when Firefox starts.

The timings that are currently reported through this API are the following:

  • process is when the Firefox process starts
  • main is when the XRE_main function is called (one of the first functions actively called)
  • firstPaint is when a web page has been displayed for the first time to the user
  • sessionRestored is pretty much self describing

There are apparently still a few rough edges, but it is still quite valuable information. As such, I wrote a little (restart-less) extension that displays these information when you go to the about:startup url. It doesn't really display the raw values, but instead the number of milliseconds elapsed since the process startup until each further event above.

Install extension.

In the long run, we should have a fully fledged extension doing that.

2011-01-19 16:12:12+0900

p.m.o | 20 Comments »

Dear lazyweb

I would like to replace my current blog with a system that mostly generates static pages, with support for comments. I'd like it to take files as input for blog posts (I'd like to store them in git), instead of database tables, and to have a flexible markup language (flexible in that it'd allow to customize the HTML output), and flexible templates.

Ikiwiki might come close to that, though I haven't looked into details. Dear lazyweb, would you know other software that'd fulfill my needs, or come close?

2011-01-16 10:12:53+0900

miscellaneous, p.d.o, p.m.o | 17 Comments »

Iceweaselボタンの代わりにアイコン

最近のIceweaselベータでメニューバーを隠して、その代わりにIceweaselボタンが表示されます。そうするにはメニューバーに右クリックして、メニューバーを無効にしたらIceweaselボタンが現れます。

あまり魅力的ではありませんし、タブバーの場所を無駄に取りますが、少しのCSSで変えられます。ユーザーのプロファイルのchrome/userChrome.cssに下記のCSSを追加して下さい:

#appmenu-toolbar-button {
  list-style-image: url("chrome://branding/content/icon16.png");
}
#appmenu-toolbar-button > .toolbarbutton-text,
#appmenu-toolbar-button > .toolbarbutton-menu-dropmarker {
  display: none !important;
}

それで、Iceweaselはこうなります:

2011-01-15 16:22:43+0900

firefox | No Comments »

Replacing the Iceweasel button with an icon

Recent Iceweasel betas allows to replace the menu bar with a Iceweasel button. This is not enabled by default, but right-clicking on the menu bar allows to disable the menu bar, which enables the Iceweasel button.

The button is not exactly very appealing, and takes quite a lot of horizontal space on the tab bar. But with a few lines of CSS, this can fortunately be changed. Edit the chrome/userChrome.css file under your user profile, and add the following lines:

#appmenu-toolbar-button {
  list-style-image: url("chrome://branding/content/icon16.png");
}
#appmenu-toolbar-button > .toolbarbutton-text,
#appmenu-toolbar-button > .toolbarbutton-menu-dropmarker {
  display: none !important;
}

This what Iceweasel looks like, then:

2011-01-15 15:49:20+0900

firefox | 20 Comments »

Replacing the Firefox button with an icon

Recent Firefox betas replaced the menu bar with a Firefox button. Under Linux, this is not enabled by default, but right-clicking on the menu bar allows to disable the menu bar, which enables the Firefox button.

The button is not exactly very appealing, and takes quite a lot of horizontal space on the tab bar. But with a few lines of CSS, this can fortunately be changed. Edit the chrome/userChrome.css file under your user profile, and add the following lines:

#appmenu-toolbar-button {
  list-style-image: url("chrome://branding/content/icon16.png");
}
#appmenu-toolbar-button > .toolbarbutton-text,
#appmenu-toolbar-button > .toolbarbutton-menu-dropmarker {
  display: none !important;
}

This what Firefox looks like, then:

2011-01-15 15:46:37+0900

p.m.o | 5 Comments »