5 ms·
re: https://github.com/uploadcare/pillow-simd#why-do-not-contribute-simd-to-the-original-pillow https://github.com/uploadcare/pillow-simd#why-do-not-contrib...
by wolf550e 10y ago
re: https://github.com/uploadcare/pillow-simd#why-do-not-contribute-simd-to-the-original-pillow https://github.com/uploadcare/pillow-simd#why-do-not-contrib...
They can create three versions of each affected function (fallback, SSE4 and AVX2), place them in separate files (one file for each set of compiler flags), compile each version with its own compiler flags, then link them all together, and in the main module (which is compiled for generic cpu) run cpuid and set global function pointers to the right function implementation.
Then always use the global function pointer to call the right implementation of the function, and only expose calling the global function pointer if the function is exported from a shared library.
They do need to make sure that function pre and post conditions are preserved in all versions and that memory alignment/layout required by optimized functions is created by the generic code.
I think x264 does this.
- asb 10y agoYou can even use the GCC ifunc attribute and get the dynamic linker to handle selecting the right function.
- btown 10y agoCertainly seems like this is the right way to go: http://clang.llvm.org/docs/AttributeReference.html#ifunc-gnu-ifunc http://clang.llvm.org/docs/AttributeReference.html#ifunc-gnu...
- dalke 10y agoIn practice, it's very hard to make Python's distutils do this. I tried to figure it out years ago, see http://stackoverflow.com/questions/15527611/how-do-i-specify-different-compiler-flags-in-distutils-for-just-one-python-c-ext http://stackoverflow.com/questions/15527611/how-do-i-specify... . I also asked on the distutils list. No one had a clean solution. The best solution I have is to interpose my own "CC", which looks at what is being compile and adds the correct compiler options for the right files before calling the real compiler. This is hacky and inflexible.
- wiredfool 10y agoI'm curious how scpiy and numpy manage it. I'm pretty sure that they have solved some of this before.
- dalke 10y agoIn my short search, I didn't see evidence that either package has run-time dispatch based on the processor type. I don't see "cpuid" used in the scipy code base, and the only intrinsic I found is specifically in a MS Windows #ifdef. Numpy doesn't use cpuid. It does have compile-time options for intrinsics, but not run-time.
- tavert 10y agoEntirely handled by the underlying BLAS library, OpenBLAS and MKL have this feature but few if any other libraries do. I believe FFTW has something similar, but scipy doesn't use FFTW.
- johnt15 10y agoIt's possible to do automatically this by using a SIMD library such as libsimdpp (https://github.com/p12tic/libsimdpp https://github.com/p12tic/libsimdpp). Everything is mostly abstracted away and you just write the SIMDified code once and add a CMake rule that builds the same file for several architectures, sets up dynamic dispatch and links everything together.