LIBPF builds with clang++
Clang++ is a new generation C++ compiler, based on a complete redesign. According to the reports it can not yet match compilation and execution time of the more mature competitors (g++, msvc, intel…), but it is growing up really quickly: the successful compilation of the boost libraries has been announced about one year ago. It was definitely time to give it a try with the LIBPF library, which we did on Debian testing (sid).
Compiling LIBPF on Debian sid, by the way, is much easier than what it used to be because over the years all the dependencies have been packaged (previously there was no libloki-dev and libsilo-dev package available). What is required nowadays to compile the LIBPF library with the default compiler on Linux (g++) is just:
apt-get install git g++ libboost1.46-dev xsltproc libloki-dev libpq-dev libsqlite3-dev libgmm++-dev libiodbc2-dev libsundials-serial-dev libmxml-dev libsilo-dev libsuitesparse-dev git clone ... cd LIBPF/src bjam
To compile with clang version 2.9-7 you need to issue the following two commands:
apt-get install clang bjam toolset=clang
Treating your (supposedly) standard-complying C++ code with a new compiler always brings in some new insight. Clang++ benefits here are the precise error / warning messages and the stricter syntax parser. The main lesson learned thanks to clang was that the right way to define a static member and instantiate a template class is:
template<> std::string PhaseIdeal<PhaseType::vapor>::type_("PhaseIdeal<vapor>"); template<> std::string PhaseIdeal<PhaseType::liquid>::type_("PhaseIdeal<liquid>"); template<> std::string PhaseIdeal<PhaseType::solid>::type_("PhaseIdeal<solid>"); template class PhaseIdeal<PhaseType::vapor>; template class PhaseIdeal<PhaseType::liquid>; template class PhaseIdeal<PhaseType::solid>;
and not the other way around (which is tolerated by all other compilers):
template class PhaseIdeal<PhaseType::vapor>; template class PhaseIdeal<PhaseType::liquid>; template class PhaseIdeal<PhaseType::solid>; template<> std::string PhaseIdeal<PhaseType::vapor>::type_("PhaseIdeal<vapor>"); template<> std::string PhaseIdeal<PhaseType::liquid>::type_("PhaseIdeal<liquid>"); template<> std::string PhaseIdeal<PhaseType::solid>::type_("PhaseIdeal<solid>");
And now some performance data, obtained on a somewhat outdated, single-core workstation:
Performance criterion | g++ 4.6.1 | clang++ 2.9-7 | ||
---|---|---|---|---|
debug | release | debug | release | |
Compilation time | 6m27.550s | 10m26.199s | 7m26.881s | 10m56.789s |
Executable size (Mbytes) | 24.1 | 7.6 | 42.1 | 10.1 |
Execution time | – | 10m10.655s | – | 11m30.840s |
Clang++ has still some way to go before entering the A league, but it is already today a valuable code compliance tool.