0

I have two classes which do the same thing, but one uses SSE4.2 and the other not. I am already detecting if the code runs on a CPU supporting SSE4.2 and using the correspondending class, but I am struggling compiling the SSE4.2 class.

I want the compiler using SSE4.2 optimation only for this class and not for the rest of the code, so I can't use -msse4.2.

I read of #pragma GCC target("sse4.2"), but I still get an compile error in the included SSE4.2-Header:

nmmintrin.h:31:3: error: #error "SSE4.2 instruction set not enabled"

How can I compile this class with SSE4.2 optimation enabled and the rest of my code disabled?

I am using GCC 4.8 & Android NDK 10d.

My class looks like this:

#include "MyClassWithSSE42.h"

#pragma GCC target("sse4.2")
#include <nmmintrin.h>

uint32_t MyClassWithSSE42::CRC32byte(const uint32_t *p, const uint32_t startValue)
{
    uint32_t c = _mm_crc32_u32(startValue, p[0]);
    c = _mm_crc32_u32(c, p[1]);
    c = _mm_crc32_u32(c, p[2]);
    c = _mm_crc32_u32(c, p[3]);
    c = _mm_crc32_u32(c, p[4]);
    c = _mm_crc32_u32(c, p[5]);
    c = _mm_crc32_u32(c, p[6]);
    return _mm_crc32_u32(c, p[7]);
}
ness
  • 41
  • 5
  • 1
    I think you need per file compiler flags. See http://stackoverflow.com/questions/7447836/per-file-cppflags-in-android-mk – Cristian Bidea Jan 23 '15 at 08:58
  • Thank you for the link. I think this is the right approach, but unfortunately I didn't it get work... – ness Jan 23 '15 at 13:33
  • You should probably include ``, and let the compiler do the rest. – Brett Hale Jan 23 '15 at 18:53
  • http://stackoverflow.com/questions/18868235/preventing-gcc-from-automatically-using-avx-and-fma-instructions-when-compiled-w/25911959#25911959 – Z boson Jan 23 '15 at 19:58
  • More recent gcc should not complain about the header (and you won't need a #pragma before #include). – Marc Glisse Jan 24 '15 at 21:01

2 Answers2

1

I don't know about the Android toolchain, but on desktop I would compile that class in a separate object file, and link it with the rest of the code.

g++ -msse4.2 -c MyClassWithSSE42.c++ -o MyClassWithSSE42.o # Compile only
g++ your_other_files.c++ MyClassWithSSE42.o                # Compile and link
user703016
  • 37,307
  • 8
  • 87
  • 112
  • Although it doesn't fit exactly my question I think this is the right way if you have to use a GCC version prior to 4.9. – ness Jan 28 '15 at 09:44
0

So I tried out GCC 4.9 as Marc Glisse mentioned it, and I get it to work! The working code now looks like this:

#include "MyClassWithSSE42.h"

__attribute__((target("sse4.2")))
uint32_t MyClassWithSSE42::CRC32byte(const uint32_t *p, const uint32_t startValue)
{
    uint32_t c = _mm_crc32_u32(startValue, p[0]);
    c = _mm_crc32_u32(c, p[1]);
    c = _mm_crc32_u32(c, p[2]);
    c = _mm_crc32_u32(c, p[3]);
    c = _mm_crc32_u32(c, p[4]);
    c = _mm_crc32_u32(c, p[5]);
    c = _mm_crc32_u32(c, p[6]);
    return _mm_crc32_u32(c, p[7]);
}

The include of <nmmintrin.h> is no longer necessary, but I had to add the target attribute in order to get it compiled.

ness
  • 41
  • 5