16

Actually I have 2 questions:

  1. Is SSE2 Compatibility a CPU issue or Compiler issue?
  2. How to check if your CPU or Compiler support SSE2?

I am using GCC Version:

gcc (GCC) 4.5.1

When I tried to compile a code it give me this error:

$ gcc -O3 -msse2 -fno-strict-aliasing -DHAVE_SSE2=1 -DMEXP=19937 -o test-sse2-M19937 test.c
cc1: error: unrecognized command line option "-msse2"

And cpuinfo showed this:

processor  : 0
vendor     : GenuineIntel
arch       : IA-64
family     : 32
model      : 1
model name : Dual-Core Intel(R) Itanium(R) Processor 9140M
revision   : 1
archrev    : 0
features   : branchlong, 16-byte atomic ops
cpu number : 0
cpu regs   : 4
cpu MHz    : 1669.000503
itc MHz    : 416.875000
BogoMIPS   : 3325.95
siblings   : 2
physical id: 0
core id    : 0
thread id  : 0
osgx
  • 90,338
  • 53
  • 357
  • 513
neversaint
  • 60,904
  • 137
  • 310
  • 477
  • You are using a GCC that is targeted to IA64 by default. The IA64 instruction set is radically different to the x86 one. If you want to compile for x86 you need to essentially cross-compile your binary. – thkala Nov 17 '10 at 10:21
  • 7
    You also have an Itanium2 processor, which has no native support for the x86 instruction set. Even if you do cross-compile your binary for x86, testing it on this system will be difficult, if not impossible. – thkala Nov 17 '10 at 10:24
  • What Linux distribution are you using by the way ? – thkala Nov 17 '10 at 10:36
  • So you wanted to test the SSE2 version of the Mersenne Twister on an Itanium. You should have asked in the first place: "Why can't I compile the SSE2 version of MT on an Itanium?" and you would have immediatly got an helpful answer. – Gunther Piez Nov 17 '10 at 11:59

5 Answers5

20

The CPU needs to be able to execute SSE2 instrcutions, and the compiler needs to be able to generate them.

To check if your cpu supports SSE2:

# cat /proc/cpuinfo

It will be somewhere under "flags" if it is supported.

Update: So you cpu doesn't support it.

For the compiler:

# gcc -dumpmachine
# gcc --version

Target of your compiler needs to a kind of x86*, since only this cpus support sse2, which is part of the x86 instruction set

AND

gcc version needs to be >= 3.1 (most likely, since this is about 10 years old or something) for supporting SSE2.

Update: So your compiler doesn't support it on this target, it will if you are using it as a cross compiler for x86.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
8

Another trick not yet mentioned is do:

gcc -march=native -dM -E - </dev/null | grep SSE2

and get:

#define __SSE2_MATH__ 1
#define __SSE2__ 1

With -march=native you are checking both your compiler and your CPU. If you give a different -march for a specific CPU, like -march=bonnell you can check for that CPU.

Consult your gcc docs for the correct version of gcc:

https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Submodel-Options.html

Bonts
  • 609
  • 9
  • 9
7
  1. It's both. The compiler/assembler need to be able to emit/handle SSE2 instructions, and then the CPU needs to support them. If your binary has SSE2 instructions with no conditions attached and you try to run it on a Pentium II you are out of luck.

  2. The best way is to check your GCC manual. For example my GCC manpage refers to the -msse2 option which will allow you to explicitly enable SSE2 instructions in the binaries. Any relatively recent GCC or ICC should support it. As for your cpu, check the flags line in /proc/cpuinfo.

It would be best, though, to have checks in your code using cpuid etc, so that SSE2 sections can be disabled in CPUs that do not support it and your code can fall back on a more common instruction set.

EDIT:

Note that your compiler needs to either be a native compiler running on a x86 system, or a cross-compiler for x86. Otherwise it will not have the necessary options to compile binaries for x86 processors, which includes anything with SSE2.

In your case the CPU does not support x86 at all. Depending on your Linux distribution, there might be packages with the Intel IA32EL emulation layer for x86-software-on-IA64, which may allow you to run x86 software.

Therefore you have the following options:

  • Use a cross-compiler that will run on IA64 and produce binaries for x86. Cross-compiler toolchains are not an easy thing to setup though, because you need way more than just the compiler (binutils, libraries etc).

  • Use Intel IA32EL to run a native x86 compiler. I don't know how you would go about installing a native x86 toolchain and all the libraries that your project needs in your distributions does not support it directly. Perhaps a full-blown chroot'ed installation of an x86 distribution ?

Then if you want to test your build on this system you have to install Intel's IA32EL for Linux.

EDIT2:

I suppose you could also run a full x86 linux distribution on an emulator like Bochs or QEMU (with no virtualization of course). You are definitely not going to be dazzled by the resulting speeds though.

thkala
  • 84,049
  • 23
  • 157
  • 201
3

Try running:

lshw -class processor | grep -w sse2

and look under the processor section.

SebMa
  • 4,037
  • 29
  • 39
Nico Huysamen
  • 10,217
  • 9
  • 62
  • 88
3

use asm to check the existence of sse2

enter code here
static
bool HaveSSE2()
{
    return false;
    __asm mov EAX,1              ;
    __asm cpuid                  ;
    __asm test EDX, 4000000h     ;test whether bit 26 is set
    __asm jnz yes                ;yes
    return false;
yes:
    return true;
}
boblehest
  • 3
  • 1
prgbenz
  • 1,129
  • 4
  • 13
  • 27
  • This looks like MSVC asm syntax, so you can't easily use it on Linux. It also looks buggy, with a `return false;` as the first statement. It would be "cleaner" to put the `yes:` label inside an asm statement; this looks like jumping to a C label from an asm statement, making the compiler's life more difficult. Probably best to just extract that bit into a true/false boolean instead of using a conditional branch. – Peter Cordes Aug 18 '17 at 15:43