zoukankan      html  css  js  c++  java
  • SIMD(MMX/SSE/AVX)变量命名规范心得

    https://www.cnblogs.com/zyl910/archive/2012/04/23/simd_var_name.html

      当使用Intrinsics函数来操作SIMD指令集(MMX/SSE/AVX等)时,会面对不同长度的SIMD数据类型,其中又分为多种紧缩格式。为此,我设计了一套SIMD变量命名规范,可以有效的提高代码的可读性。

    一、SIMD数据类型简介

      SIMD数据类型有——
    __m64:64位紧缩整数(MMX)。
    __m128:128位紧缩单精度(SSE)。
    __m128d:128位紧缩双精度(SSE2)。
    __m128i:128位紧缩整数(SSE2)。
    __m256:256位紧缩单精度(AVX)。
    __m256d:256位紧缩双精度(AVX)。
    __m256i:256位紧缩整数(AVX)。
    注:紧缩整数包括了8位、16位、32位、64位的带符号和无符号整数。

      这些数据类型与寄存器的对应关系为——
    64位MM寄存器(MM0~MM7):__m64。
    128位SSE寄存器(XMM0~XMM15):__m128、__m128d、__m128i。
    256位AVX寄存器(YMM0~YMM15):__m256、__m256d、__m256i。

    二、SIMD变量命名规范

      参考匈牙利命名法(Hungarian notation),在变量名前面增加类型前缀。
      类型前缀为3个小写字母,首字母代表寄存器宽度,最后两个字母代表紧缩数据类型。

      寄存器宽度(首字母)——
    m:64位MM寄存器。对应 __m64
    x:128位SSE寄存器。对应 __m128、__m128d、__m128i。
    y:256位AVX寄存器。对应 __m256、__m256d、__m256i。

      紧缩数据类型(两个字母)——
    mb:8位数据。用于只知道长度、不知道具体紧缩格式时。(b:Byte)
    mw:16位数据。(w:Word)
    md:32位数据。(d:DoubleWord)
    mq:64位数据。(q:QuadWord)
    mo:128位数据。(o:OctaWord)
    mh:256位数据。(h:HexWord)
    ub:8位无符号整数。
    uw:16位无符号整数。
    ud:32位无符号整数。
    uq:64位无符号整数。
    ib:8位带符号整数。
    iw:16位带符号整数。
    id:32位带符号整数。
    iq:64位带符号整数。
    fh:16位浮点数,即半精度浮点数。(h:Half)
    fs:32位浮点数,即单精度浮点数。(s:Single)
    fd:64位浮点数,即双精度浮点数。(d:double)

      例如——
    mub:64位紧缩字节(64位MMX寄存器,其中存放了8个8位无符号整数)。
    xfs:128位紧缩单精度(128位SSE寄存器,其中存放了4个单精度浮点数)。
    xid:128位紧缩带符号字(128位SSE寄存器,其中存放了4个32位带符号整数)。
    yfd:256位紧缩双精度(256位AVX寄存器,其中存放了4个双精度浮点数)。
    yfh:256位紧缩半精度(256位AVX寄存器,其中存放了16个半精度浮点数)。

    三、示例代码

      例如SSE累加求和程序——
    复制代码

    int sum3_Intrinsics(int *a, int size)
    {
        if (NULL==a)    return 0;
        if (size<0)    return 0;
    
        int s = 0;    // 返回值
        __m128i xidSum = _mm_setzero_si128();    // 累积。[SSE2] 赋初值0
        __m128i xidLoad;    // 加载
        int cntBlock = size / 4;    // 块数。SSE寄存器能一次处理4个DWORD
        int cntRem = size & 3;    // 剩余数量
        __m128i* p = (__m128i*)a;
        for(int i = 0; i < cntBlock; ++i)
        {
            xidLoad = _mm_load_si128(p);    // [SSE2] 加载
            xidSum = _mm_add_epi32(xidSum, xidLoad);    // [SSE2] 带符号32位紧缩加法
            ++p;
        }
    
        // 处理剩下的
        int* q = (int*)p;
        for(int i = 0; i < cntRem; ++i)    s += q[i];
    
        // 将累加值合并
        xidSum = _mm_hadd_epi32(xidSum, xidSum);    // [SSSE3] 带符号32位水平加法
        xidSum = _mm_hadd_epi32(xidSum, xidSum);
        s += _mm_cvtsi128_si32(xidSum);    // [SSE2] 返回低32位
    
        return s;
    }
    

    复制代码

      代码出自——
    http://topic.csdn.net/u/20120102/01/fc8d7aa4-bffc-4d9a-a34a-5056c6d27b54.html

    9楼

  • 相关阅读:
    IE调试页面总结
    解决XAMPP不能启动Apche服务问题
    WCF与Ajax开发实践系列课程
    Team Foundation 中的错误和事件消息
    设置SVN提交日志必填
    MyBatis.Net 学习手记
    PandorBox 中安装aria2失败的解决办法
    Linux 启动出现 busybox vx.x.xx built-in shell 的问题
    Sql Server 中查询存储过程的修改时间
    ubuntu挂载和挂载NTFS分区命令
  • 原文地址:https://www.cnblogs.com/marklove/p/14256753.html
Copyright © 2011-2022 走看看