文档章节

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

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:46
字数 1186
阅读 40
收藏 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
粉丝 64
博文 6421
码字总数 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
6.9K
4
armeabi和armeabi-v7a 以及x86

原文:http://blog.csdn.net/dxpqxb/article/details/7721156 armeabi和armeabi-v7a 在我们android APK的根目录有一个 libs文件夹,此文件夹下包含了armeabi 和armeabi-v7a两个文件夹,我们的...

QGlaunch
2015/12/23
125
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
5
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0
一、Django基础

一、web框架分类和wsgiref模块使用介绍 web框架的本质 socket服务端 与 浏览器的通信 socket服务端功能划分: 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn... 根据用户访问...

ZeroBit
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部