Multicore Programming SIMD

  • SIMD介绍
  • SSE的指令Streaming SIMD Extensions
    • 函数命名
    • 举例应用

转载请注明出处:http://blog.csdn.net/c602273091/article/details/55045956

SIMD介绍

single instruction multiple data就是一条指令执行很多个一样的操作。比如128位的浮点运算,那么128位就可以同时计算4组float类型的数据运算。在intel的处理器中,定义了一套这样的运算SSE。

SSE的指令(Streaming SIMD Extensions)

指令集包括:64 bit MMX、128 bit SSE、 256 bit AVX、512 比他AVX-512
使用头文件#include < intrin.h> 就可以使用所有的指令。
具体头文件参考:

http://www.cnblogs.com/wangguchangqing/p/5466301.html

甚至AVX-512指令集有512位的寄存器,那么相对应Intrinsic的数据也就有512位。
具体的数据类型及其说明如下:

__m64 64位对应的数据类型,该类型仅能供MMX指令集使用。由于MMX指令集也能使用SSE指令集的128位寄存器,故该数据类型使用的情况较少。
__m128 / __m128i / __m128d 这三种数据类型都是128位的数据类型。由于SSE指令集即能操作整型,又能操作浮点型(单精度和双精度),这三种数据类型根据所带后缀的不同代表不同类型的操作数。__m128是单精度浮点数,__m128i是整型,__m128d是双精度浮点数。256和512的数据类型和128位的只是把位数替换一下。

函数命名

第一部分为前缀_mm,表示是SSE指令集对应的Intrinsic函数。_mm256或_mm512是AVX,AVX-512指令集的Intrinsic函数前缀;
第二部分为对应的指令的操作,如_add,_mul,_load等,有些操作可能会有修饰符,如loadu将未16位对齐的操作数加载到寄存器中。
第三部分为操作的对象名及数据类型,_ps packed操作所有的单精度浮点数;_pd packed操作所有的双精度浮点数;_pixx(xx为长度,可以是8,16,32,64)packed操作所有的xx位有符号整数,使用的寄存器长度为64位;_epixx(xx为长度)packed操作所有的xx位的有符号整数,使用的寄存器长度为128位;_epuxx packed操作所有的xx位的无符号整数;_ss操作第一个单精度浮点数。

这一段描述来自于:

http://www.cnblogs.com/wangguchangqing/p/5466301.html

举例应用

void ComputeArrayWithSSE(  
          float* a1,                   // [in] first source array  
          float* a2,                   // [in] second source array  
          float* res,                  // [out] result array  
          int size)                   // [in] size of all arrays  
{  
    int numLoop = size >> 2;  

    __m128 m1, m2, m3, m4;  

    __m128* pSrc1 = (__m128*) a1;  
    __m128* pSrc2 = (__m128*) a2;  
    __m128* pDest = (__m128*) res;  


    __m128 m0_5 = _mm_set_ps1(0.5f);        // m0_5[0, 1, 2, 3] = 0.5  

    for ( int j = 0; j < numLoop; j++ )  
    {  
        m1 = _mm_mul_ps(*pSrc1, *pSrc1);        // m1 = *pSrc1 * *pSrc1  
        m2 = _mm_mul_ps(*pSrc2, *pSrc2);        // m2 = *pSrc2 * *pSrc2  
        m3 = _mm_add_ps(m1, m2);                // m3 = m1 + m2  
        m4 = _mm_sqrt_ps(m3);                   // m4 = sqrt(m3)  
        *pDest = _mm_add_ps(m4, m0_5);          // *pDest = m4 + 0.5  

        pSrc1++;  
        pSrc2++;  
        pDest++;  
    }  
}  

参考链接:

intel的指令集说明:https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf

http://blog.csdn.net/chenchong_219/article/details/44683155

https://msdn.microsoft.com/zh-cn/library/ayeb3ayc.aspx

http://www.cnblogs.com/wangguchangqing/p/5466301.html

http://stackoverflow.com/questions/18638051/using-avx-with-gcc-avxintrin-h-missing

AVX的介绍:

http://blog.csdn.net/fengbingchun/article/details/23598709

http://stackoverflow.com/questions/32612190/how-to-solve-the-32-byte-alignment-issue-for-avx-load-store-operations

https://software.intel.com/zh-cn/forums/intel-isa-extensions/topic/515997

https://neal.hackpad.com/ep/pad/static/W3RmB2yYv3E

https://software.intel.com/zh-cn/articles/avoiding-avx-sse-transition-penalties/

你可能感兴趣的:(CMU:,How,to,Write,Fast,Code,18-645:How,to,Write,Fast,Code)