Optimization in GCC
The optimizations discussed thus far can yield significant improvements in software performance and object size, but specifying the target architecture also can yield meaningful benefits. The -march option of gcc allows the CPU type to be specified (Table 2).
Table 2. x86 Architectures
|Target CPU Types||-march= Type|
|AMD K6 II||k6-2|
|AMD K6 III||k6-3|
|AMD Athlon 4||athlon|
|AMD Athlon XP/MP||athlon|
The default architecture is i386. GCC runs on all other i386/x86 architectures, but it can result in degraded performance on more recent processors. If you're concerned about portability of an image, you should compile it with the default. If you're more interested in performance, pick the architecture that matches your own.
Let's now look at an example of how performance can be improved by focusing on the actual target. Let's build a simple test application that performs a bubble sort over 10,000 elements. The elements in the array have been reversed to force the worst-case scenario. The build and timing process is shown in Listing 1.
Listing 1. Effects of Architecture Specification on a Simple Application
[mtj@camus]$ gcc -o sort sort.c -O2 [mtj@camus]$ time ./sort real 0m1.036s user 0m1.030s sys 0m0.000s [mtj@camus]$ gcc -o sort sort.c -O2 -march=pentium2 [mtj@camus]$ time ./sort real 0m0.799s user 0m0.790s sys 0m0.010s [mtj@camus]$
By specifying the architecture, in this case a 633MHz Celeron, the compiler can generate instructions for the particular target as well as enable other optimizations available only to that target. As shown in Listing 1, by specifying the architecture we see a time benefit of 237ms (23% improvement).
Although Listing 1 shows an improvement in speed, the drawback is that the image is slightly larger. Using the size command (Listing 2), we can identify the sizes of the various sections of the image.
Listing 2. Size Change of the Application from Listing 1
[mtj@camus]$ gcc -o sort sort.c -O2 [mtj@camus]$ size sort text data bss dec hex filename 842 252 4 1098 44a sort [mtj@camus]$ gcc -o sort sort.c -O2 -march=pentium2 [mtj@camus]$ size sort text data bss dec hex filename 870 252 4 1126 466 sort [mtj@camus]$
From Listing 2, we can see that the instruction size (text section) of the image increased by 28 bytes. But in this example, it's a small price to pay for the speed benefit.
Some specialized optimizations require explicit definition by the developer. These optimizations are specific to the i386 and x86 architectures. A math unit, for one, can be specified, although in many cases it is automatically defined based on the specification of a target architecture. Possible units for the -mfpmath= option are shown in Table 3.
Table 3. Math Unit Optimizations
|387||Standard 387 Floating Point Coprocessor|
|sse||Streaming SIMD Extensions (Pentium III, Athlon 4/XP/MP)|
|sse2||Streaming SIMD Extensions II (Pentium 4)|
The default choice is -mfpmath=387. An experimental option is to specify both sse and 387 (-mfpmath=sse,387), which attempts to use both units.
- Nmap—Not Just for Evil!
- Resurrecting the Armadillo
- High-Availability Storage with HA-LVM
- March 2015 Issue of Linux Journal: System Administration
- Real-Time Rogue Wireless Access Point Detection with the Raspberry Pi
- DNSMasq, the Pint-Sized Super Dæmon!
- Localhost DNS Cache
- Days Between Dates: the Counting
- The Usability of GNOME
- Linux for Astronomers