Search code examples
c++visual-studioneonintel-ipp

Switching Between High Performance Libraries in c++


I am writing some C++ code to target various platforms. This includes x86, x64, and ARM. I currently use Intel IPP and MKL (for SSE) on x64 and expect to add a NEON library for ARM. Is there a standard way to branch around specific libraries and with minimal dependencies and fuss? I am currently using Visual Studio 2008 or 2012.

My initial thought is to just #ifdef around specific calls and test for X86, X64, ARM, etc. Like:

void addVectors(int * a, int * b, int n)
{

   #ifdef INTELIPP
      ippsAdd_32s_I(...);
   #elif ARMNEON
      neonAdd_32s_I(...);
   #else
      for(int k = 0; k < n; k++)
         a[k] += b[k];
   #endif

}

but this could get really messy. I was wondering what the standard approach is. For example, I expect it to be cleaner to a separate project for the IPP and NEON code and only build the main project against one of them?

The IDE is not terribly important except for support---and I suspect we will change over to something like Eclipse for the ARM work.


Solution

  • I'm pretty sure that the only other option besides lots of preprocessor junk is to have different files for different platforms, and the build process will select the file for the architecture you're targeting for a particular library. The downside to this is that if there are more complicated functions, maintaining the different implementations of the same function so that they all behave identically gets a little more tricky. In some cases you may want to use a common file or macros to implement aspects of functions that are common across architectures. For example:

    • MyFFT.h (Public API)
    • MyFFT_Intel.c
    • MyFFT_Neon.c
    • MyFFT_CrossPlatform.c (Plain C implementation)
    • MyFFT_Common.c
    • MyFFT_Private.h (For common helper functions prototypes implemented in MyFFT_Common.c)

    Of course, having lots of unit tests is really key for all cross-platform abstractions like this.

    One other thing to consider is CPU dispatching. If you are running on ARM, for example, you may want to detect if NEON is present at runtime. IPP does under the hood for Intel variants, but as ARM matures and NEON capabilities change the same way SSE has, you may need to implement your own dispatching mechanism unless you are using a 3P product that handles this for you.