如何测试您的Linux是否支持SSE2

16

实际上我有两个问题:

  1. SSE2兼容性是CPU问题还是编译器问题?
  2. 如何检查您的CPU或编译器是否支持SSE2?

我正在使用的GCC版本:

gcc (GCC) 4.5.1

当我尝试编译代码时,它给了我这个错误:

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

并且 cpuinfo 显示了以下内容:

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

你正在使用默认针对IA64的GCC。IA64指令集与x86指令集截然不同。如果你想编译x86,你需要实质上进行交叉编译。 - thkala
7
您也拥有一个Itanium2处理器,该处理器没有原生支持x86指令集。即使您将二进制文件交叉编译为x86架构,测试它在这个系统上仍然会很困难,甚至不可能。 - thkala
你用的是哪个 Linux 发行版呢? - thkala
所以你想在Itanium上测试Mersenne Twister的SSE2版本。你应该一开始就问:“为什么我不能在Itanium上编译MT的SSE2版本?”这样你会立即得到有用的答案。 - Gunther Piez
5个回答

21

计算机处理器需要支持执行SSE2指令,编译器也需要能够生成这些指令。

要检查您的CPU是否支持SSE2:

# cat /proc/cpuinfo

如果支持的话,它会在“flags”下面的某个地方。

更新:所以你的 CPU 不支持它。

对于编译器:

# gcc -dumpmachine
# gcc --version

你的编译器的目标需要是x86*类型,因为只有这些处理器支持SSE2指令集。

而且,gcc版本需要大于等于3.1(最可能是这样,因为这已经大约10年左右了),才能支持SSE2。

更新:如果你的编译器在此目标上不支持它,那么如果你将其用作x86交叉编译器,则会支持。


我认为SSE/SSE2支持是在GCC-3.1中引入的。 - thkala
是的,你说得对:http://gcc.gnu.org/gcc-3.1/changes.html。我已经更新了我的回答。 - Gunther Piez
grep -o sse2 /proc/cpuinfo 很有用,因为在某些CPU上,需要通过眼睛查看很多标志。 - Peter Cordes

8

还有一个尚未提及的技巧是使用“do”:

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

并获得:

#define __SSE2_MATH__ 1
#define __SSE2__ 1

使用 -march=native 选项可以同时检查编译器和 CPU。如果您为特定的 CPU 指定不同的 -march,例如 -march=bonnell,则可以检查该 CPU。

请查阅您的 gcc 文档以获取正确的 gcc 版本:

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


我该如何停用SSE2? - Mona Jalal
@dentad 很棒的答案,我喜欢它因为它是可移植的 :-) - SebMa

7
  1. The compiler/assembler需要能够发出/处理SSE2指令,CPU需要支持它们。如果您的二进制文件具有无条件附加的SSE2指令,并尝试在Pentium II上运行它,则会失败。
  2. 最好的方法是查看您的GCC手册。例如,我的GCC man页面提到了-msse2选项,这将允许您在二进制文件中明确启用SSE2指令。任何相对较新的GCC或ICC都应该支持它。至于您的CPU,请检查/ proc / cpuinfo中的标志行。

但最好在您的代码中使用cpuid等检查,以便可以在不支持它的CPU上禁用SSE2部分,您的代码可以回退到更常见的指令集。

编辑:

请注意,您的编译器需要是在x86系统上运行的本地编译器,或者是用于x86的交叉编译器。否则,它将没有必要的选项来编译x86处理器的二进制文件,包括任何带有SSE2的内容。

在您的情况下,CPU根本不支持x86。根据您的Linux发行版,可能会有包含Intel IA32EL仿真层的软件,用于在IA64上运行x86软件,这可能允许您运行x86软件。

因此,您有以下选项:

  • 使用可以在IA64上运行并生成x86二进制文件的交叉编译器。交叉编译器工具链不是易于设置的事情,因为您需要比编译器(binutils、库等)更多的东西。
  • 使用Intel IA32EL运行本机x86编译器。如果您的发行版没有直接支持它,则不知道如何在您的项目中安装本机x86工具链和所有所需的库。也许是完整的chroot'ed x86发行版安装?

然后,如果您想在此系统上测试构建,则必须安装Intel的Linux IA32EL。

编辑2:

我想您也可以在像Bochs或QEMU这样的模拟器上运行完整的x86 Linux发行版(当然没有虚拟化)。但是,您绝对不会被结果速度所迷惑。


谢谢。请看上面的更新。如何检查标志,我的CPU信息似乎没有显示出来。 - neversaint

3

请尝试运行:

lshw -class processor | grep -w sse2

并查看处理器部分。


3

使用asm检查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;
}

这看起来像是MSVC汇编语法,所以你不能轻易地在Linux上使用它。它看起来也有漏洞,因为return false;是第一条语句。将yes:标签放在一个asm语句内会更加“清晰”;这看起来像是从asm语句跳转到C标签,使编译器的工作更加困难。最好只需将该位提取为真/假布尔值,而不是使用条件分支。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接