SIMD Everywhere (SIMDe) is another way to get C/C++ applications with intrinsics running on Arm.
Like sse2neon it is a header-only library which makes porting code to other architectures easy.
If the code being migrated has MMX or SSE code then either sse2neon or SIMDe can be used, but if it contains AVX then SIMDe is needed.
To make the example application compile and run on Arm there are four steps:
SIMDE_ENABLE_NATIVE_ALIASES macro before the include to enable original _mm intrinsics to be recognizedThe use of SIMDE_ENABLE_NATIVE_ALIASES is not recommended for large projects.
It is recommended to rename the intrinics with simde prepended. For example, change _mm_set_ps to simde_mm_set_ps in the below.
Using the simde prefix is recommended for new code.
The appropriate header file for emmintrin.h is simde/x86/sse2.h
Here is the new code (neon.cpp). The only change is related to the include files, and the definition of SIMDE_ENABLE_NATIVE_ALIASES.
#include <iostream>
#define SIMDE_ENABLE_NATIVE_ALIASES
#if defined(__SSE2__) || defined(__aarch64__)
#include "simde/x86/sse2.h"
#else
#warning SSE2/NEON support is not available. Code will not compile.
#endif
int main(int argc, char **argv)
{
__m128 a = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
__m128 b = _mm_set_ps(8.0, 7.0, 6.0, 5.0);
__m128 c = _mm_add_ps(a, b);
float d[4];
_mm_storeu_ps(d, c);
std::cout << "result equals " << d[0] << "," << d[1]
<< "," << d[2] << "," << d[3] << std::endl;
return 0;
}
This can be compiled and run on your Arm instance using the commands below.
Install wget, git, and g++ compiler, and use appropriate g++ command options:
sudo apt install -y git g++ wget
git clone https://github.com/simd-everywhere/simde.git
g++ -O2 -I simde/ -march=armv8.2-a+fp16+rcpc+dotprod+crypto --std=c++14 neon.cpp -o neon
Run the code:
./neon
and observe the output:
result equals 6,8,10,12
For more information on the use of SIMDe, see the below blog.