CPU指令集不同导致的core分析

最近程序需要支持CGSL系统运行,测试中发现相同操作系统的两台机器,编译机运行正常,测试机coredump。core信息汇总如下,可以看出是由于测试机不支持编译后的指令导致的问题:

Program terminated with signal 4, Illegal instruction.

   0x00007fad269ac973 <+435>:   add    $0x4,%rdx
   0x00007fad269ac977 <+439>:   lea    -0x1010101(%rcx),%eax
=> 0x00007fad269ac97d <+445>:   andn   %eax,%ecx,%eax
   0x00007fad269ac982 <+450>:   and    $0x80808080,%eax

   0x00007f26c8b37e87 <+181>:   lea    0x28(%rax),%rsi
   0x00007f26c8b37e8b <+185>:   mov    -0x38(%rbp),%rax
=> 0x00007f26c8b37e8f <+189>:   vmovdqa -0x60(%rbp),%xmm0
   0x00007f26c8b37e94 <+194>:   vmovdqu %xmm0,0x10(%rsp)
   0x00007f26c8b37e9a <+200>:   movl   $0x0,0x8(%rsp)

   0x00007f2f5d5c282e <+216>:   js     0x7f2f5d5c2837
=> 0x00007f2f5d5c2830 <+218>:   vcvtsi2ss %rax,%xmm0,%xmm0
   0x00007f2f5d5c2835 <+223>:   jmp    0x7f2f5d5c284c
   0x00007f2f5d5c2837 <+225>:   mov    %rax,%rdx

两台机器操作系统完全一致,内核和gcc版本如下:

[CGSLv5]# uname -a
Linux CGSLv5-2965 3.10.0-693.21.1.el7.x86_64 #1 SMP Fri Mar 30 15:43:35 CST 2018 x86_64 x86_64 x86_64 GNU/Linux
[CGSLv5]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-ZTEOS-linux/4.8.5/lto-wrapper
Target: x86_64-ZTEOS-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-ZTEOS-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-ZTEOS-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-ZTEOS-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
[CGSLv5]#

  

通过<<Intel? 64 and IA-32 Architectures Software Developer’s Manual>>查询汇编指令andn/vmovdqa/vcvtsi2ss归属的指令集, 可以看到这三个指令分别归属与BMI1/AVX

查询编译机和测试机的CPU信息和flags如下,确认测试机不支持BMI1/AVX/AVX2(也可以参考Intel对E5-2680和E5260的介绍):

编译机器:
[[email protected]]# cat /proc/cpuinfo | grep "model name" | uniq -c
     56 model name      : Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz

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 pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts

测试机器:
[[email protected]]# cat /proc/cpuinfo | grep "model name" | uniq -c
     16 model name      : Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz

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 pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 popcnt aes lahf_lm epb tpr_shadow vnmi flexpriority ept vpid dtherm arat

针对指令集的问题,GCC可以通过设置编译选项-march/-mtune来处理,具体参考<<Intel 386 and AMD x86-64 Options>>,截取一部分如下:

-march=cpu-type
  Generate instructions for the machine type cpu-type. In contrast to -mtune=cpu-type, which merely tunes the generated code for the specified cpu-type, -march=cpu-type allows GCC to generate code that may not run at all on processors other than the one indicated. Specifying -march=cpu-type implies -mtune=cpu-type.

The choices for cpu-type are:
‘native’
  This selects the CPU to generate code for at compilation time by determining the processor type of the compiling machine. Using -march=native enables all instruction subsets supported by the local machine (hence the result might not run on different machines). Using -mtune=native produces code optimized for the local machine under the constraints of the selected instruction set.
‘core2’
  Intel Core 2 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support.
‘corei7’
  Intel Core i7 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 instruction set support.
‘corei7-avx’
  Intel Core i7 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AES and PCLMUL instruction set support.
‘core-avx2’
  Intel Core CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2 and F16C instruction set support. 

一般来说编译时设置了-march=native,才会出现本地机器指令集都支持,但很有可能导致编译后的程序不能在其它机器上运行的结果。查询编译选项发现-march=native,删除后通过objdump反汇编编译后程序确认不再生成BMI/AVX指令,测试机器验证运行正常。

修改前:
[CGSLv5]# objdump -d libTest.so  | grep vcvtsi2ss
   63830:       c4 e1 fa 2a c0          vcvtsi2ss %rax,%xmm0,%xmm0
   63843:       c4 e1 fa 2a c2          vcvtsi2ss %rdx,%xmm0,%xmm0
   640a6:       c4 e1 fa 2a c0          vcvtsi2ss %rax,%xmm0,%xmm0
   640b9:       c4 e1 fa 2a c1          vcvtsi2ss %rcx,%xmm0,%xmm0
   640d3:       c4 e1 f2 2a ca          vcvtsi2ss %rdx,%xmm1,%xmm1
   640e6:       c4 e1 f2 2a c8          vcvtsi2ss %rax,%xmm1,%xmm1
   64123:       c4 e1 f2 2a ce          vcvtsi2ss %rsi,%xmm1,%xmm1
   64136:       c4 e1 f2 2a cf          vcvtsi2ss %rdi,%xmm1,%xmm1
   64172:       c4 e1 f2 2a ce          vcvtsi2ss %rsi,%xmm1,%xmm1
   64185:       c4 e1 f2 2a cf          vcvtsi2ss %rdi,%xmm1,%xmm1
   641a2:       c4 e1 fa 2a c0          vcvtsi2ss %rax,%xmm0,%xmm0
   641b5:       c4 e1 fa 2a c2          vcvtsi2ss %rdx,%xmm0,%xmm0
[CGSLv5]#

修改后:
[CGSLv5]# objdump -d libTest.so  | grep vcvtsi2ss
[CGSLv5]#

当然,也可以直接指定选项-march的值,像我的机器查询出来有以下几种cpu-type,可以通过指定 -march=corei7 来屏蔽BMI/AVX/AVX2指令集:

[localhost]# gcc -c -Q -march=native --help=target  | grep -E "avx|arch"
  -march=                               core-avx2
  -mavx                                 [enabled]
  -mavx2                                [enabled]
  -mavx256-split-unaligned-load         [disabled]
  -mavx256-split-unaligned-store        [disabled]
  -mprefer-avx128                       [disabled]
  -msse2avx                             [disabled]

  -march=                               corei7
  -mavx                                 [disabled]
  -mavx2                                [disabled]
  -mavx256-split-unaligned-load         [disabled]
  -mavx256-split-unaligned-store        [disabled]
  -mprefer-avx128                       [disabled]
  -msse2avx                             [disabled]

  -march=                               corei7-avx
  -mavx                                 [enabled]
  -mavx2                                [disabled]
  -mavx256-split-unaligned-load         [disabled]
  -mavx256-split-unaligned-store        [disabled]
  -mprefer-avx128                       [disabled]
  -msse2avx                             [disabled]
  -mtune=                               corei7-avx

几个问题:

1. 如果GCC编译选项没有设置-march, 那么默认这个选项是什么?
2. 理论来讲,设置-march=native可以使用本机器支持的全部指令集,从而得到更优的性能,但降低了程序对不同机器的兼容性;不设置-march=native或设置为其它选项虽然理论上降低了程序性能,但程序兼容性大大增加;如何取舍?

可以参考的网址:

Intel? Xeon? Processor E5620(Intel? SSE4.2):
https://ark.intel.com/products/47925/Intel-Xeon-Processor-E5620-12M-Cache-2-40-GHz-5-86-GT-s-Intel-QPI-

Intel? Xeon? Processor E5-2680(Intel? AVX):
https://ark.intel.com/products/64583/Intel-Xeon-Processor-E5-2680-20M-Cache-2-70-GHz-8-00-GT-s-Intel-QPI-

gcc-online-docs:
https://gcc.gnu.org/onlinedocs/

i386-x86-64-option of gcc4.8.5:
https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Option-Summary.html#Option-Summary
https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/i386-and-x86-64-Options.html#i386-and-x86-64-Options

avx(Advanced Vector Extensions):
https://software.intel.com/zh-cn/articles/introduction-to-intel-advanced-vector-extensions
https://software.intel.com/en-us/blogs/2015/01/15/vector-programming-sse42-to-avx2-conversion-examples
https://software.intel.com/en-us/articles/introduction-to-intel-advanced-vector-extensions

Intel? 64 and IA-32 Architectures Software Developer’s Manual:
https://software.intel.com/en-us/articles/intel-sdm

x86/amd64 fast online instruction reference from Intel Architectures Software Developer’s Manual:
http://www.felixcloutier.com/x86/

原文地址:https://www.cnblogs.com/aios/p/9955339.html

时间: 2024-10-12 02:32:04

CPU指令集不同导致的core分析的相关文章

一次服务器CPU占用率高的定位分析

背景 通过性能监控发现上线服务器cpu某核占用率已经达到了100%,而且是由我们的某个核心服务导致的.幸亏由于我们的服务进程由多个相同worker(线程)调度承担的,所以除了CPU占用率高之外,并没有对服务造成影响.随着上次我们找到那个吃IO的罪犯,这次我们要追捕的是潜伏在团体中的特务,更加惊险刺激哟! 系统环境 用top命令很容易定位到是谁占用CPU最高. 以我们的这个业务进程(imDevServer)举例,为什么说这货是个潜伏者呢?因为这是个多线程的进程,我们要知道实际上占用cpu的最小单位

修改手机CPU指令集的教程

给大家讲一个手机比较底层参数值的修改,也就是手机的CPU指令集,同样的我们需要用琢石模拟器这个强大的工具来帮我们完成这个修改. 如果您没有安装琢石模拟器,请到琢石模拟器的官网ZS8K.COM下载并按照教程进行激活. 接下来我们演示一下如何通过琢石模拟器来修改CPU的指令集. 1.首先我们先看在没有使用琢石模拟器之前,获取到的手机指令集是什么内容?图中可以看到,真实的手机指令集是“armeabi-v7a,armeabi” 2.我们打开琢石模拟器,进入虚拟环境列表,找到CPU类型跟CPU类型2,这2

CPU指令集

cpu作为一台电脑中的核心,它的作用是无法替代的.而cpu本身只是在块硅晶片上所集成的超大规模的集成电路,集成的晶体管数量可达到上亿个,是由非常先进复杂的制造工艺制造出来的,拥有相当高的科技含量. CPU指令集 - 概念 CPU依靠指令来计算和控制系统,每款CPU在设计时就规定了一系列与其硬件电路相配合的指令系统.指令的强弱也是CPU的重要指标,指令集是提高微处理器效率的最有效工具之一.从现阶段的主流体系结构讲,指令集可分为复杂指令集和精简指令集两部分,而从具体运用看,如Intel的MMX(Mu

编译TensorFlow CPU指令集优化版

编译TensorFlow CPU指令集优化版 如题,CPU指令集优化版,说的是针对某种特定的CPU型号进行过优化的版本.通常官方给的版本是没有针对特定CPU进行过优化的,有网友称,优化过的版本相比优化前的版本性能提升大概30%. 下面简单介绍下在Ubuntu上进行Tensor Flow编译 必要的环境: bazel, 这玩意的安装方法参考别的资料,比较麻烦 sudo apt-get install python-numpy python-dev python-pip python-wheel 因

【转】STM32擦除内部FLASH时间过长导致IWDG复位分析

@20119-01-29 [小记] STM32擦除内部FLASH时间过长导致IWDG复位分析 原文地址:https://www.cnblogs.com/skullboyer/p/10335371.html

透过SQL语法来查询目前CPU的相关数据(例如Core)

摘要:透过SQL语法来查询目前CPU的相关数据(例如Core) 可以透过下列语法来查询CPU的Core Count> SELECT cpu_count/hyperthread_ratio AS sockets FROM sys.dm_os_sys_info; GO 当然sys.dm_os_sys_info这个数据表内有更多资讯,就等你自己去挖掘啦. 适用SQL Server版本:2005 参考出处:http://blogs.msdn.com/buckwoody/archive/2007/08/1

delete数组引发的core分析

delete [] ptr 引发了singnal 6 abort的core错误,跟踪过程发现写入ptr大量数据,引发内存越界,破坏了new数组的尾部数据保护,导致delete的时候core. 问题分析过程写了一段测试代码,发现另外一些编辑器或者说操作系统的性质,new申请的数组总是分配2的n次方的空间,比如char* ptr = new char[10]实际分配了16个字节的空间 ,char* ptr2 = new char[15]同样分配了16个空间的字节,而char* ptr3 = new

ubuntu mysql5.6 数据库占用CPU过高导致机器卡死

五一当天,公司下午2点,数据库的机器突然访问不了.应用不能访问了.客户无法使用!客服同志打电话通知,我当时在外面陪女儿玩,周边没有电脑.为了应付紧急状况,马上重启了机器.重启后可以使用了.具体什么原因导致这一的现象还要仔细分析. 第一步,找出宕机半个小时之内的CPU,内存,网络等检测数据!检测结果是这样的: 从上面四个图可以看出,内存和网络正常,只有CPU从13:50开始一直使用过高,突然增长到90%! 由此分析出 原因一,Query查询响应过慢,也就是个别查询占用时间太长. 原因二,磁盘出问题

用户CPU占用过大后的分析过程

找到最耗CPU的java线程ps命令 命令:ps -mp pid -o THREAD,tid,time   或者  ps -Lfp pid 结果展示: 这个命令的作用,主要是可以获取到对应一个进程下的线程的一些信息. 比如你想分析一下一个java进程的一些运行瓶颈点,可以通过该命令找到所有当前Thread的占用CPU的时间,也就是这里的最后一列. 比如这里找到了一个TID : 30834 ,所占用的TIME时间最高. 通过 printf "%x\n" 30834 首先转化成16进制,