RSSAmplifier

The Cranky Developer on Crater Moon Development · Nov 13, 2004

Firefox Burning

0
Sign in to vote or save

Steven E. Newton · Crater Moon Development

853 words. (5 min)

Firefox Optimized

As a programmer, one of the things I love about being able to get the source to my favorite tools is then I can learn from it and build it to my specifications. Recently I got the source to Firefox 1.0 and played around with optimizing the build for my desktop machine, an AMD Athlon 1GHz. Not that the generic Firefox builds from the Mozilla foundation were slow, but I wanted to see what was possible. The hardest part was finding the right gcc options that would work and generate acceptable code. My first few attempts failed in the middle of the build because various intermediate build products, like xpidl, would crash when trying to process some step, because they had been built with bad options.

Using gcc 3.3.5 I end up with the following optimization flags:

-march=athlon-tbird -mmmx -m3dnow -O3 -funroll-loops -fomit-frame-pointer

I tried various fastmath options but in general I couldn’t get a good build. I don’t know how much math a browser really needs to do, anyway, so I didn’t spend too much time on it.

I would not assert that the resulting binary is spectacularly faster, but there are places where it seems snappier. If you want to try yourself, in addition to the build instructions from Mozilla, here are the settings and scripts I used. I’d be interested to hear of your experiences, and in particular if you have any tips for getting the fastmath options to work.

GCC Details

The specific gcc I used, as reported by gcc -v

    Configured with: ../src/configure -v
    --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang
    --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info
    --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared
    --with-system-zlib --enable-nls --without-included-gettext
    --enable-__cxa_atexit --enable-clocale=gnu --enable-debug
    --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux
    Thread model: posix
    gcc version 3.3.5 (Debian 1:3.3.5-2)

My .mozconfig

The complete set of build options for Firefox.

    . $topsrcdir/browser/config/mozconfig
    export MOZILLA_OFFICIAL=1
    export BUILD_OFFICIAL=1
    mk_add_options MOZILLA_OFFICIAL=1
    mk_add_options BUILD_OFFICIAL=1
    ac_add_options --enable-strip
    ac_add_options --enable-strip-libs
    # Optimization configurations
    ac_add_options --enable-optimize="-march=athlon-tbird -mmmx -m3dnow -O3 -funroll-loops -fomit-frame-pointer"
    ac_add_options --disable-logging
    ac_add_options --disable-tests
    ac_add_options --disable-debug
    ac_add_options --enable-default-toolkit=gtk2
    ac_add_options --enable-xft
    #ac_add_options --enable-freetype2
    mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/firefox-bin

GCC CPU Options script

Here’s the script I found that helped me find the options for my CPU.

    #!/bin/sh

    # Author: pixelbeat

    #This script is Linux specific
    #It should work on any gcc >= 2.95 at least

    #these apply to any arch (just here for reference)
    unsafe_math_opts="-ffast-math -fno-math-errno -funsafe-math-optimizations -fno-trapping-math"

    gcc_version=`gcc -dumpversion | sed 's/\([0-9]\{1,\}\.[0-9]\{1,\}\)\.*\([0-9]\{1,\}\)\{0,1\}/\1\2/'`

    IFS=":"
    while read name value; do
        unset IFS
        name=`echo $name`
        value=`echo $value`
        IFS=":"
        if [ "$name" == "vendor_id" ]; then
            vendor_id="$value"
        elif [ "$name" == "cpu family" ]; then
            cpu_family="$value"
        elif [ "$name" == "model" ]; then
            cpu_model="$value"
        elif [ "$name" == "flags" ]; then
            flags="$value"
        fi
    done < /proc/cpuinfo
    unset IFS

    if [ "$vendor_id" == "AuthenticAMD" ]; then
        if [ "$cpu_family" == "4" ]; then
            _CFLAGS="$_CFLAGS -march=i486"
        elif [ "$cpu_family" == "5" ]; then
            if [ "$cpu_model" -lt "4" ]; then
                _CFLAGS="$_CFLAGS -march=pentium"
            elif [ "$cpu_model" == "6" ] || [ "$cpu_model" == "7" ]; then
                _CFLAGS="$_CFLAGS -march=k6"
            elif [ "$cpu_model" == "8" ] || [ "$cpu_model" == "12" ]; then
                if expr $gcc_version '>=' 3.1 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=k6-2"
                else
                    _CFLAGS="$_CFLAGS -march=k6"
                fi
            elif [ "$cpu_model" == "9" ] || [ "$cpu_model" == "13" ]; then
                if expr $gcc_version '>=' 3.1 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=k6-3"
                else
                    _CFLAGS="$_CFLAGS -march=k6"
                fi
            fi
        elif [ "$cpu_family" == "6" ]; then
            if [ "$cpu_model" -le "3" ]; then
                if expr $gcc_version '>=' 3.0 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=athlon"
                else
                    _CFLAGS="$_CFLAGS -march=k6"
                fi
            elif [ "$cpu_model" == "4" ]; then
                if expr $gcc_version '>=' 3.1 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=athlon-tbird"
                elif expr $gcc_version '>=' 3.0 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=athlon"
                else
                    _CFLAGS="$_CFLAGS -march=k6"
                fi
            elif [ "$cpu_model" -ge "6" ]; then #athlon-{4,xp,mp}
                if expr $gcc_version '>=' 3.1 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=athlon-xp"
                elif expr $gcc_version '>=' 3.0 >/dev/null; then
                    _CFLAGS="$_CFLAGS -march=athlon"
                else
                    _CFLAGS="$_CFLAGS -march=k6"
                fi
            fi
        fi
    else #everything else "GenuineIntel"
        if [ "$cpu_family" == "3" ]; then
            _CFLAGS="$_CFLAGS -march=i386"
        elif [ "$cpu_family" == "4" ]; then
            _CFLAGS="$_CFLAGS -march=i486"
        elif [ "$cpu_family" == "5" ] && expr $gcc_version '<' 3.1 >/dev/null; then
            _CFLAGS="$_CFLAGS -march=pentium"
        elif [ "$cpu_family" -ge "6" ] && expr $gcc_version '<' 3.1 >/dev/null; then
            _CFLAGS="$_CFLAGS -march=pentiumpro"
        elif [ "$cpu_family" == "5" ]; then
            if [ "$cpu_model" != "4" ]; then
                _CFLAGS="$_CFLAGS -march=pentium"
            else
                _CFLAGS="$_CFLAGS -march=pentium-mmx" #No overlap with other vendors
            fi
        elif [ "$cpu_family" == "6" ]; then
            if echo "$flags" | grep -vq cmov; then #gcc incorrectly assumes i686 always has cmov
                _CFLAGS="$_CFLAGS -march=pentium -mcpu=pentiumpro" #VIA CPUs exhibit this
            else
                if [ "$cpu_model" == "0" ] || [ "$cpu_model" == "1" ]; then
                    _CFLAGS="$_CFLAGS -march=pentiumpro"
                elif [ "$cpu_model" -ge "3" ] && [ "$cpu_model" -le "6" ]; then #4=TM5600 at least 
                    _CFLAGS="$_CFLAGS -march=pentium2"
                elif [ "$cpu_model" -ge "7" ] && [ "$cpu_model" -le "11" ]; then #9 invalid
                    _CFLAGS="$_CFLAGS -march=pentium3"
                fi
            fi
        elif [ "$cpu_family" == "15" ]; then
            _CFLAGS="$_CFLAGS -march=pentium4"
        fi
    fi

    if expr $gcc_version '>=' 3.1 >/dev/null; then
        if echo "$flags" | grep -q sse2; then
            _CFLAGS="$_CFLAGS -mfpmath=sse -msse2"
        elif echo "$flags" | grep -q sse; then
            _CFLAGS="$_CFLAGS -mfpmath=sse -msse"
        fi
        if echo "$flags" | grep -q mmx; then
            _CFLAGS="$_CFLAGS -mmmx"
        fi
        if echo "$flags" | grep -q 3dnow; then
            _CFLAGS="$_CFLAGS -m3dnow"
        fi
    fi

    echo "$_CFLAGS"

<-Reporting Is A Code Smell Cem Kaner at PNSQC 2003 ->

Read the original on cmdev.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.