文档章节

SSE特殊指令集系列之一----各种数据重排指令

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:46
字数 1186
阅读 37
收藏 0

实际上,搞汇编优化的很多时间是在处理如何有效的组织数据,以适应并行计算指令的数据结构。

本小结描述的是数据混洗指令,这类指令使用起来相当的灵活。具体如下:

 

   1.  shufps  XMM,XMM/m128,imm8(0~255)

       描述:

           从指令后缀来看,这是一条SSE1指令。

           该指令把源存储器与目的寄存器按双字32位划分, 由立即数imm8八个二进制位(00~11,00^11,00~11,00~11)指定排列,

           目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数。内存变量地址必须对齐16字节

           imm8的高4位选的是源存储器,低4位选的是目的寄存器。

                      高64位 | 低64位

        目的寄存器:         a(11) | a(10) | a(01) | a(00)
        源寄存器:          b(11) | b(10) | b(01) | b(00)
        目的寄存器排列结果:       b(00~11) | b(00~11) | a(00~11) | a(00~11)
        目的寄存器压缩结果中的值由imm8对应的两位二进制位指定.

      例:
         ( 11 ) ( 10 ) ( 01 ) ( 00 ) ( 11 ) ( 10 ) ( 01 ) ( 00 )
      当    XMM0 = 0x 090a0b0c 0d0e0f11 01020304 05060708,

                        XMM1 = 0x 0aabbccdd eeff1234 22334455 66778899,

              mm8  ══> (XMM1 10) (XMM1 01) (XMM0 11) (XMM0 00)

         执行shufps XMM0,XMM1,10 01 11 00 b(二进制),

                         则XMM0 = 0x 0eeff1234 22334455 090a0b0c 05060708

                  

         假如,shufps XMM0,XMM1,10 10 10 10 b,那么结果为:    XMM0 = 0x 0eeff1234 eeff1234 0d0e0f11 0d0e0f11

 

                      该指令一个常用用法如下:

                      float f = 0.5f;

        __asm

        {

                      movss   xmm2, f                         // xmm2[0] = 2.8
                      shufps  xmm2, xmm2, 0                   // xmm2[1, 2, 3] = xmm2[0]

        .....

        }

                       

 2.   shufpd XMM,XMM/m128,imm8(0~255) 

        描述:

         从指令后缀来看,这是一条SSE2指令。

         imm8(操作值) = imm8(输入值) mod 4

   把源存储器与目的寄存器按四字64位划分,由imm8(立即数)4个二进制位(0~1,0~1,0~1,0~1)指定排列,
   内存变量地址必须对齐16字节.目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数.
                    高64位 | 低64位
       目的寄存器:          a(1) | a(0)
       源寄存器:           b(1) | b(0)
       目的寄存器排列结果:      b(0~1) | a(0~1)
    例:
      当    XMM0 = 0x 1111111122222222 3333333344444444
         XMM1 = 0x 5555555566666666 aaaaaaaacccccccc,

                   执行 shufpd XMM0,XMM1,101001 1 0 b

        因为 101001 1 0 b mod 4 (101001 1 0 b & 11b), 得到操作值为1 0b,  

        高位 1 选择源寄存器 XMM1 的第1位  5555555566666666,

                   低位 0 选择目的寄存器XMM0的第0位   3333333344444444.


         则 XMM0 = 5555555566666666 3333333344444444 h
      

 3.  pshuflw XMM,XMM/m128,imm8(0~255)

      描述:  

  先把源存储器的高64位内容送入目的寄存器的高64位,然后用imm8将源存储器的低64位4个字选入
  目的寄存器的低64位,内存变量必须对齐内存16字节.

                            低64位
      源寄存器低64位:          b(11) | b(10) | b(01) | b(00)
      目的寄存器低64位排列结果:   b(00~11) | b(00~11) | b(00~11) | b(00~11)

  例:
  当 XMM0 = 0x 1111111122222222 3333 4444 5555 6666
    XMM1 = 0x 5555555566666666 7777 8888 9999 cccc ,

    执行 pshuflw XMM0,XMM1,10 10 01 10 b
  则  XMM0 = 0x 5555555566666666 8888 8888 9999 8888

 

4.  pshufhw XMM,XMM/m128,imm8(0~255)

  描述:

      先把源存储器的低64位内容送入目的寄存器的低64位,然后用imm8将源存储器的高64位4个字选入
  目的寄存器的高64位,内存变量必须对齐内存16字节.
                      高64位
  源寄存器高64位:           b(11) | b(10) | b(01) | b(00)
  目的寄存器高64位排列结果:  b(00~11) | b(00~11) | b(00~11) | b(00~11)
  例:
  当 XMM0 = 0x 3333 4444 5555 6666 1111111122222222
      XMM1 = 0x 7777 8888 9999 cccc 5555555566666666,

     执行 pshufhw XMM0,XMM1,10 10 01 10 b
  则  XMM0 = 0x 8888 8888 9999 8888 5555555566666666

5.  pshufd XMM,XMM/m128,imm8(0~255)

  描述:

  将源存储器的4个双字由imm8指定选入目的寄存器,内存变量必须对齐内存16字节.
                高64位 | 低64位
  源寄存器:          (11) | b(10) | b(01) | b(00)
  目的寄存器排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
  例:
  当 XMM1 = 0x 11111111 22222222 33333333 44444444,

     执行 pshufd XMM0,XMM1,11 01 01 10b
  则 XMM0 = 0x 11111111 33333333 33333333 22222222


6.  pshufw  MM, MM/m64, imm8(0~255)

      此指令属于MMX的指令。上面描述的pshuflwpshufhw 都是它的扩展,执行相同的功能。

     只是pshuflw执行的是XMM寄存器的低64位,pshufhw执行XMM寄存器的高64位。


      这条指令的功能和pshufd 指令执行的操作一样,只是它操作数据的单位是16位的一个字。


 

 小结:

    1. SHUFPS和SHUFPD指令运算的结果与源寄存器和目的寄存器有关

      2. pshufw、pshuflw、pshufhw、pshufd这3条指令运算的结果与目的寄存器没有关系。

 

 

 

 

本文转载自:http://www.cnblogs.com/celerychen/archive/2013/04/23/3588217.html

共有 人打赏支持
abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
私信 提问
Intel 45nm制程处理器上的SSE4指令集简介

Intel 45nm制程处理器上的SSE4指令集简介 Intel的SSE(Streaming SIMD Extensions, 流式单指令多数据扩展)技术有效增强了CPU的向量运算能力。支持该指令集的处理器有8个128位xmm寄存器,每一...

日久不生情
2017/11/07
0
0
如何选择纠删码编码引擎 | 纠删码技术详解(上)

作者介绍: 徐祥曦,七牛云工程师,独立开发了多套高性能纠删码/再生码编码引擎。 柳青,华中科技大学博士,研究方向为基于纠删码的分布式存储系统。 前言: 随着数据的存储呈现出集中化(以...

七仙女很忙
2017/04/13
0
0
实现高性能纠删码引擎 | 纠删码技术详解(下)

作者介绍: 徐祥曦,七牛云工程师,独立开发了多套高性能纠删码/再生码编码引擎。 柳青,华中科技大学博士,研究方向为基于纠删码的分布式存储系统。 前言: 在上篇《如何选择纠删码编码引擎...

七仙女很忙
2017/05/24
0
0
[高并发Java 三] Java内存模型和线程安全

网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存。数据在主存中会有一份,在工作内存中也有一份。工作内存和主存之间会有各种原子操作去进行同...

Hosee
2016/01/08
4.4K
3
漫画:volatile对指令重排的影响

点击上方“程序员小灰”,选择“置顶公众号” 有趣有内涵的文章第一时间送达! 上一期介绍了volatile关键字对JVM主内存和工作内存的影响,没看过的小伙伴们可以点击下面链接: 什么是 volati...

bjweimengshu
2017/12/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux syslog相关函数详解

介绍 syslog是Unix系统的日志系统。可以将日志记录在本地系统中。 一个完整的syslong日志包含如下信息:程序模块 | 严重性 | 时间 | 主机名 | 进程名 | 进程ID | 正文。 syslong相关函数 1....

RongJinhui0
18分钟前
0
0
使用nsenter工具进入Docker容器

查看本机装没有nsenter whereis nsenter或者whatis nsenter 未安装先安装,网上有很多这样的脚本 vi nsenter.sh#!/bin/bashcurl https://www.kernel.org/pub/linux/utils/util-linux/v2....

问题终结者
18分钟前
2
0
MaxCompute安全管理指南-基础篇

背景及目的 方便和辅助MaxCompute的project owner或安全管理员进行project的日常安全运维,保障数据安全。 MaxCompute有安全模型,DataWorks也有安全模型,当通过DataWorks使用MaxCompute,而...

阿里云云栖社区
19分钟前
1
0
Retrofit设计模式源码解析

因为Retrofit做到了很强的解耦,因此就一定需要用到很多设计模式。所以,我觉得,通过阅读Retrofit源码来学习设计模式是再好不过的设计模式学习方法了。 大致看了一圈Retrofit源码,受益匪浅...

亭子happy
19分钟前
4
0
哈夫曼编码

哈夫曼编码的基本思想是以字符的使用频率作为权构建一颗哈夫曼树,然后利用 哈夫曼树对字符进行编码 哈夫曼算法采用的贪心策略是每次从树的集合中取出没有双亲权值最小的两棵作为左右子树, ...

writeademo
21分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部