• SSE指令集


    本篇介绍sse指令接,sse是流化SIMD扩展(Streaming SIMD Extension, SSE),提供全新的一组寄存器,处理128位打包数据。

    sse提供了xmm寄存器,xmm一组8个128位的寄存器,分别名为xmm0-xmm7,sse构架提供对打包单精度浮点数的SIMD支持。

    sse提供了两个版本的指令,其一以后缀ps结尾,这组指令对打包单精度浮点值执行类似mmx操作运算,而第二种后缀ss,这些指令对一个量标单精度浮点 值进行运算操作,这些指令不对打包值中的所有浮点值操作,而只对打包值中的低位双字节执行操作,源操作数中剩余的3个值直接传送给结果。

    指令说明
    movaps 把4个对准的单精度值传送到xmm寄存器或者内存
    movups 把4个不对准的单精度值传送到xmm寄存器或者内存
    movss 把1个单精度值传送到内存或者寄存器的低位双字
    movlps 把2个单精度值传送到内存或者寄存器的低四字
    movhps 把2个单精度值传送到内存或者寄存器的高四字
    movlhps 把2个单精度值从低四字传送到高四字
    movhlps 把2个单精度值从高四字传送到低四字

    其中对准操作movaps要求数据在内存中对准16字节的边界,以提交效率,否则应使用movups传送数据。

    运算指令:

    指令说明
    addps 将两个打包值相加
    subps 将两个打包值相减
    mulps 将两个打包值相乘
    divps 将两个打包值相除
    rcpps 计算打包值的倒数
    sqrtps 计算打包值的平方根
    rsqrtps 计算打包值的平方根倒数
    maxps 计算两个打包值中的最大值
    minps 计算两个打包值中的最小值
    andps 计算两个打包值的按位逻辑与
    andnps 计算两个打包值的按位逻辑非
    orps 计算两个打包值的按位逻辑或
    xorps 计算两个打包值的按位逻辑异或

    以上指令都是用两个操作数:源操作数可以是128位内存或者xmm寄存器,目标操作数必须是xmm寄存器。

    这里举一个简单的例子,使用gdb查看最后结果:

    .section .data
        value1: .float 12.12, 34.89, 56.23, 78.45
        value2: .float 31.12, 57.124, 234.23, 67.246
    .section .text
    .globl _main
    _main:
        enter $0, $0
    
        movups value1, %xmm0
        movups value2, %xmm1
        addps %xmm0, %xmm1
    
        movups value2, %xmm1
        maxps %xmm0, %xmm1
        leave
        ret
    

    编译时加-g参数加入调试信息,调用addps后查看xmm1寄存器的结果,命令如下:

    (gdb) print $xmm1
    $1 = {v4_float = {43.2400017, 92.0139999, 290.459991, 145.695999},
      v2_double = {26419069594869.762, 1245245520236216.2}, v16_int8 = {-61, -11,
        44, 66, 43, 7, -72, 66, -31, 58, -111, 67, 45, -78, 17, 67}, v8_int16 = {
        -2621, 16940, 1835, 17080, 15073, 17297, -19923, 17169}, v4_int32 = {
        1110242755, 1119356715, 1133591265, 1125233197}, v2_int64 = {
        4807600484593235395, 4832839782622116577},
      uint128 = 0x4311b22d43913ae142b8072b422cf5c3}
    (gdb)
    

    可以看到,调用加法指令之后,四组和都存储在xmm1寄存器中,gdb查看时由于不知道如何解析xmm1寄存器的内容,因为可能是单精度,也可能是双精度或者不同宽度的整数,所以只能按不同的解析方式全部显示,查看v4_float即四个单精度浮点数的显示。

    下面介绍一下sse构架下的比较指令,sse的比较指令单独比较128位打包单精度浮点的每个元素,结果是一个掩码,满足比较条件的结果全为1值,不满足结果的全为0值(量标只对最低的双字执行)。

    指令说明
    cmpps 比较打包值
    cmpss 比较标量值
    comiss 比较标量值并且设置eflags寄存器
    ucomiss 比较标量值(包括非法值)并设置eflags寄存器

    看到这里,仅仅有一个比较指令,并没有说明大小,何为满足条件全1,不满足全0呢,这样说一下指令的使用:

    cmpps imp, source, destination
    

    其中多出来的imp是一个无符号整数,这个整数表示的含义就是条件,这个条件值如下表所示:

    整数说明
    0 等于
    1 小于
    2 小于或等于
    3 无序
    4 不等于
    5 不小于
    6 不小于或等于
    7 有序

    如果需要比较两个数是否相等,传imp为0即可作为条件,满足条件结果全1,这是sse的比较方式。这里说明一下条件中的无序,因为是浮点比较,寄存器或内存中的有些值并不符合规定的浮点存储格式,相互比较是没有意义的,称为无序。

    除了对浮点数的支持,sse指令集也有指令对mmx提供的功能进行扩展,他们对mmx寄存器中的数据执行操作:

    指令说明
    pavgb 计算打包无符号字节整数的平均值
    pavgw 计算打包无符号字整数的平均值
    pextrw 把一个字从mmx寄存器复制到通用寄存器
    pinsrw 把一个字从通用寄存器复制到mmx寄存器
    pmaxub 计算打包无符号字节整数的最大值
    pmaxsw 计算打包有符号字整数的最大值
    pminub 计算打包无符号字节整数的最小值
    pminsw 计算打包有符号字整数的最小值
    pmulhuw 将打包无符号字整数相乘并且存储高位结果
    psadbw 计算无符号字节整数的绝对差的总和

    SSE2 指令集又对 SSE 指令集做了很多扩充,主要对操作双精度浮点数和128位打包整数值执行数学操作,下面介绍SSE2的使用,先来看数据传送指令:

    指令说明
    movapd 把2个对准的双精度值传送到xmm寄存器或者内存
    movupd 把2个不对准的双精度值传送到xmm寄存器或者内存
    movdqa 把2个对准的四字节整数传送到xmm寄存器或者内存
    movdqu 把2个不对准的四字节整数传送到xmm寄存器或者内存
    movsd 把1个双精度值传送到内存或者寄存器的低四字
    movhpd 把1个双精度值传送到内存或者寄存器的高四字
    movlpd 把1个双精度值传送到内存或者寄存器的低四字

    SSE2指令集提供处理打包双精度浮点数,打包字整数,打包双字整数和打包四字整数值的数学指令,这里列举SSE2的加法指令来说明这一系列指令格式:

    指令说明
    addpd 将打包双精度浮点值相加
    addsd 将量标双精度浮点值相加
    paddsb 将打包带符号字节整数相加
    paddsw 将打包带符号字整数相加
    paddd 将打包带符号双字整数相加
    paddq 将打包带符号四字整数相加

    这里虽然只列举add系列指令,这些选项也存在于乘法和除法操作中(mulpd, mulsd, divpd, divsd等)。 另外同sse指令集,sse2指令集也提供专门的数学操作,sqrt, max, min。

    最后我们来看SSE3指令集,SSE3构架并没有提供任何新的数据类型,仅仅添加了几条指令,用于更快的执行标准函数,下面是新指令的列表:

    指令说明
    fisttp 把第一个fpu寄存器的值转换为整数(舍入)并且从fpu堆栈弹出
    lddqu 快速从内存加载128位不对准的数据值
    movshdup 传送128位值,复制第2个和第4个32位数据元素
    movsldup 传送128位值,复制第1个和第3个32位数据元素
    movddup 传送64位值,赋值值,使之成为128位值
    addsubps 对于打包单精度浮点数,对第2个和第4个32位执行加法,第1和第3个32位执行减法
    addsubpd 对于打包单精度浮点数,对第2对64位值执行加法,第1对位执行减法
    haddps 对操作数的相邻的元素执行单精度浮点加法操作
    haddpd 对操作数的相邻的元素执行双精度浮点加法操作
    hsubps 对操作数的相邻的元素执行单精度浮点减法操作
    hsubpd 对操作数的相邻的元素执行双精度浮点减法操作

    SSE指令繁多,这里举得例子却很少,以后我会在此文继续附加一些说明例子,方便理解。

    转载:http://fancymore.com/reading/assembler-sse-instruct.html

  • 相关阅读:
    Visual Studio 2008 菜单:工具+选项+文本编辑器+HTML+格式,选中“键入时插入属性值引号”
    itemarray的意思
    SQL技巧大全
    IIS调用com组件的权限问题
    网站快速备案法(1小时)
    ASP.NET 2.0中WEB应用程序的部署
    c#中MessageBox的使用
    推荐一款DataGridView的打印解决方案
    使用C#格式化字符串
    关于MSSQL导入导出时主键与约束丢失的问题解决
  • 原文地址:https://www.cnblogs.com/DeeLMind/p/7367768.html
Copyright © 2020-2023  润新知