SIMD技术简介


发布于 2024-09-07 / 41 阅读 / 0 评论 /
SIMD是单指令流多数据流技术

1.SIMD简介

SIMD(Single Instruction, Multiple Data)是一种计算机处理器的并行计算技术,允许一条指令同时操作多个数据元素。如下图所示:

而传统的计算模式下,使用标量运算一次只能对一对数据执行乘法操作,要实现上述SIMD的一次操作,需要4次标量(Scalar)运算,如下图所示:

这种技术可用于提高程序的执行速度和效率,特别适用于需要执行相同操作的大量数据的场景。

SIMD使得处理器能够同时处理多个数据并行执行相同操作,从而减少指令级并行和数据级并行所需的周期数。

2.SIMD发展历史

20世纪70年代,SIMD首次引用于ILLIAC IV大规模并行计算机上。

1996年,Intel推出了X86的MMX(MultiMedia eXtension)指令集扩展,MMX定义了8个寄存器,称为MM0到MM7,以及对这些寄存器进行操作的指令。每个寄存器为64位宽,可用于以“压缩”格式保存64位整数或多个较小整数,然后可以将单个指令一次应用于两个32位整数,四个16位整数或8个8位整数。

1999年,Intel又推出了全面覆盖MMX的SSE(Streaming SIMD Extensions, 流式SIMD扩展)指令集,并将其应用到Pentium III系列处理器上,SSE添加了八个新的128位寄存器(XMM0至XMM7),而后来的X86-64扩展又在原来的基础上添加了8个寄存器(XMM8至XMM15)。SSE支持单个寄存器存储4个32位单精度浮点数,之后的SSE2则支持单个寄存器存储2个64位双精度浮点数,2个64位整数或4个32位整数或8个16位短整形。SSE2之后还有SSE3,SSE4以及AVX,AVX2等扩展指令集。

20世纪90年代末,SIMD大规模应用到消费级计算机。

3.SIMD应用场景

在SIMD中,一条指令会被发送到多个处理单元,这些处理单元同时对它们所管理的数据进行操作。这种方式比传统的每个处理单元执行不同指令的方式更为高效,特别适用于许多数值计算和多媒体处理任务。

SIMD技术在图形处理、信号处理、加密算法等领域广泛应用,能够显著提高程序的性能和吞吐量。

4.SIMD使用方式

SIMD有多种使用方式,如下图所示:

4.1.IPP函数库

首先是最简单的方法是使用Intel开发的跨平台函数库(IPP,Intel Integrated Performance Primitives ),里面的函数实现都使用了SIMD指令进行优化。

4.2.编译器Auto-vecorization

借助于Auto-vectorization(自动矢量化),借助编译器将标量操作转化为矢量操作。

4.3.编译器指示符(compiler directive)

如Cilk里的#pragma simd和OpenMP里的#pragma omp simd。如下所示,使用#pragma simd强制循环矢量化:

void add_floats(float * a,float * b,float * c,float * d,float * e,int n)
{
    int i;
    #pragma simd
    for(i = 0; i <n; i ++)
    {
        a [i] = a [i] + b [i] + c [i] + d [i] + e [i];
    }
}

4.4.内置函数(intrinsics)

此种方法则是使用内置函数(intrinsics)的方式,如下所示,使用SSE mmadd_ps 内置函数,一次执行8个单精度浮点数的加法:

int  main()
{
    __m128 v0 = _mm_set_ps(1.0f, 2.0f, 3.0f, 4.0f);
    __m128 v1 = _mm_set_ps(1.0f, 2.0f, 3.0f, 4.0f);

    __m128 result = _mm_add_ps(v0, v1);
}

4.5.汇编语言操作寄存器

最底层方法则是使用汇编直接操作寄存器,直接使用汇编有点复杂。