I am one of the maintainers of the ntl package, which is used by some
numeric applications (e.g., Macaulay2 and sagemath). Upstream
supports use of the PCLMUL instruction, the AVX instructions, and the
FMA instructions to speed up various computations. We can't use any
of those in Fedora, since we have to support a baseline x86_64.
Well, that's kind of a downer. I could advertise that people with
newer CPUs ought to rebuild the ntl package for their own CPUs, but
what's a distribution for if people have to rebuild packages? I've
been looking for a way to automatically support more recent CPUs.
Yesterday I sent a patch upstream that uses gcc's indirect function
support together with __attribute__((target ...)) to build vanilla
x86_64, PCLMUL-enabled, AVX-enabled, and FMA-enabled varieties of
several functions. Upstream was initially excited about this but
then, on further reflection, offered the opinion that this approach is
dangerous. The problem is that some of the types involved may change
ABI depending on the instruction set in use, and therefore it would be
necessary to build larger portions of the library for each supported
CPU variant. At that point, as upstream said, we might as well just
build the entire library for each variant. The problem then is how to
choose which version of the library to use at load time.
On some platforms, ld.so offers "hardware capabilities", such as sse2
on i386. By dropping a vanilla library into /usr/lib and an
SSE2-enabled build into /usr/lib/sse2, applications can get the
version of the library appropriate for the CPU in use. But there
don't seem to be any defined hardware capabilities for x86_64.
Has anybody already thought this through? What's the best approach to
take? For this package, the speedups are substantial, so this is
worth doing, if it can be done well.