使用 -mpopcnt 编译会导致 Illegal instruction 错误
Compiling with -mpopcnt causes Illegal instruction error
我编译了下面的C++代码
// main.cpp
#include <cstdio>
int main() {
unsigned char tab[4] = {0};
printf("%d\n", __builtin_popcount(*((int *)tab)));
}
使用命令行:
g++ -o prog main.cpp -mpopcnt
当我 运行 程序时出现错误:
Illegal instruction
不使用 -mpopcnt 进行编译不会出错(它只会打印 0)。
问题:导致此错误的原因是什么?
我正在同一台机器上编译和 运行ning 程序。
Valgrind 没有检测到问题。 运行
valgrind --leak-check=full ./prog
给予
==12917== Memcheck, a memory error detector
==12917== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12917== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==12917== Command: ./prog
==12917==
0
==12917==
==12917== HEAP SUMMARY:
==12917== in use at exit: 0 bytes in 0 blocks
==12917== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==12917==
==12917== All heap blocks were freed -- no leaks are possible
==12917==
==12917== For counts of detected and suppressed errors, rerun with: -v
==12917== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
下面我给出了我的系统的一些规格。
我正在使用 Ubuntu 12.04。 运行
uname -a
给我
Linux wtu-82 3.2.0-65-generic #99-Ubuntu SMP Fri Jul 4 21:03:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
运行
g++ -v
给予
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.4-1ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04)
的输出
cat /proc/cpuinfo
是
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz
stepping : 10
microcode : 0xa0c
cpu MHz : 2000.000
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips : 6317.48
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz
stepping : 10
microcode : 0xa0c
cpu MHz : 2000.000
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips : 6317.38
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
POPCNT
是在 SSE 4.2
中引入的。您的处理器是 SSE 4.1
。所以,指令根本就不见了。当您使用 -mpopcnt
强制编译器使用您的处理器不知道的指令生成代码时,您会遇到非法指令错误。
我编译了下面的C++代码
// main.cpp
#include <cstdio>
int main() {
unsigned char tab[4] = {0};
printf("%d\n", __builtin_popcount(*((int *)tab)));
}
使用命令行:
g++ -o prog main.cpp -mpopcnt
当我 运行 程序时出现错误:
Illegal instruction
不使用 -mpopcnt 进行编译不会出错(它只会打印 0)。
问题:导致此错误的原因是什么?
我正在同一台机器上编译和 运行ning 程序。 Valgrind 没有检测到问题。 运行
valgrind --leak-check=full ./prog
给予
==12917== Memcheck, a memory error detector
==12917== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12917== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==12917== Command: ./prog
==12917==
0
==12917==
==12917== HEAP SUMMARY:
==12917== in use at exit: 0 bytes in 0 blocks
==12917== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==12917==
==12917== All heap blocks were freed -- no leaks are possible
==12917==
==12917== For counts of detected and suppressed errors, rerun with: -v
==12917== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
下面我给出了我的系统的一些规格。
我正在使用 Ubuntu 12.04。 运行
uname -a
给我
Linux wtu-82 3.2.0-65-generic #99-Ubuntu SMP Fri Jul 4 21:03:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
运行
g++ -v
给予
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.4-1ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04)
的输出
cat /proc/cpuinfo
是
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz
stepping : 10
microcode : 0xa0c
cpu MHz : 2000.000
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips : 6317.48
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Duo CPU E8500 @ 3.16GHz
stepping : 10
microcode : 0xa0c
cpu MHz : 2000.000
cache size : 6144 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips : 6317.38
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
POPCNT
是在 SSE 4.2
中引入的。您的处理器是 SSE 4.1
。所以,指令根本就不见了。当您使用 -mpopcnt
强制编译器使用您的处理器不知道的指令生成代码时,您会遇到非法指令错误。