Contents
Introduction
Recent versions of PowerVM Lx86 make use of the Power6 processor's little-endian mode to avoid the cost of explicitly converting data from little-endian to big-endian. For some complex operations like the x86's fsin and fcos instructions however, Lx86 needs to make use of the Power platform's maths library (libm.so), and so needs to switch back to big-endian mode to make the library call. For some applications that make heavy use of these complex operations, the switching between modes can lead to poor performance.
In many cases, use of the complex x86 instructions such as fsin, fcos and similar is restricted to the x86 math library. However it is possible to create a math library which uses generic implementations of its routines which just use standard FP instructions, rather than making use of the special instructions that the x86 provides. While this wouldn't provide as good performance on a normal x86, the performance through Lx86 is much improved.
This document describes a method of creating an alternative x86 math library for use with PowerVM Lx86. This example uses RHEL4.7, but the steps are similar for other versions of Linux, such as RHEL5 and SLES10.
 | Warning
Libraries built in this way have not been subject to the normal testing or certification process, and so should be used with caution - test thoroughly on a development system first, and use at your own risk. |
Obtaining the source RPM
On most systems, libm.so comes as part of the glibc package. To create the new version of the library, it is necessary to rebuild this package from the sources, and the simplest way to do this is to find the source rpm - for RHEL4.7 systems, the file needed is glibc-2.3.4-2.41.src.rpm. This can be found on the fourth source CD, or the equivalent ISO image (RHEL4.7-i386-source-disc4.iso). The package is also available on the source DVD (RHEL4.7-i386-source-DVD.iso).
On an x86 machine (or under PowerVM Lx86, of course) install this RPM as follows:
root@x86 # rpm -ivh glibc-2.3.4-2.41.src.rpm
Any warnings about users/groups not existing can be safely ignored.
Modifying the configure flags
The build is controlled by the glibc.spec file, so this is what needs to be modified to pass the correct arguments to the glibc build system. The extra flag to be added is '--without-fp' - this has to be appended to each call to configure in the .spec file. To do this, enter the following commands:
root@x86 # cd /usr/src/redhat/SPECS
root@x86 # mv glibc.spec glibc.spec.bk
root@x86 # sed "s$\.\.\/configure$\.\.\/configure --without-fp$" glibc.spec.bk > glibc.spec
With the glibc provided in RHEL4, there are some additional modifications to make to this build to allow the libraries to link correctly. These changes can also be made in the .spec file - the following lines should be added at the end of the %prep section, just before the '%build' line:
for f in s_isnanl.c s_isinfl.c s_finitel.c
do
mv sysdeps/ieee754/ldbl-96/$f sysdeps/ieee754/ldbl-96/$f.bk
grep -v hidden_def sysdeps/ieee754/ldbl-96/$f.bk > sysdeps/ieee754/ldbl-96/$f
done
Note that this step is not required on RHEL5.
Building the libraries
Once the modifications to the glibc.spec file have been made, the libraries can be compiled using rpmbuild. Still in the /usr/src/redhat/SPECS directory, issue the following command:
This will extract the sources, apply various patches, and then configure, build and package the libraries. Note that this may take some time to complete.
The final RPMS will be placed in /usr/src/redhat/RPMS, but in this case only the math library itself is needed. When the build has finished, this library will be available here:
/usr/src/redhat/BUILD/glibc-2.3.6/build-i386-linux/math/libm.so.6
Using the new library
Once you have built the new library, make it available to your x86 World and start Lx86:
root@power # runx86
root@lx86 # cp libm.so.6 /mylibs
root@lx86 # export LD_LIBRARY_PATH=/mylibs
Now, when you run your application in this Lx86 session, it should pick up the new library. If your applications makes heavy use of the complex math library routines, you should see significantly improved performance.
Testing a microbenchmark which makes many repeated calls to the sin() function, using PowerVM Lx86 v1.3.0, I see a runtime of 157s using the standard libm. When I set my LD_LIBRARY_PATH to include my new library, the test completes in only 29s.
Questions or discussion?