向量化技术
向量由具有相同标量数据类型的多个元素组成。向量长度是指一起处理的向量元素数,通常为2、4、8或16个元素。
例如,128位宽的向量寄存器可以处理八个16位的短整数。在这种情况下,向量长度为8。理想情况下,向量长度由开发人员或编译器选择,以匹配基础向量寄存器的宽度。
向量化是一种转换循环的过程,该循环遍历多对数据项并为每对数据分配一个单独的处理单元。每个处理单元都属于一个向量通道。向量通道的数量与向量长度相同,因此,可以使用尽可能多的向量通道同时处理2、4、8或16个数据项。例如,考虑将大小为1024个元素的数组和数组相加,并将结果写入数组,其中和与的大小相同。要实现此加法,使用标量代码需要1024次循环迭代。但是,如果在处理单元中有8个向量通道,则可以一起处理数组的8个元素的向量,因此仅需要128(1024/8)次迭代。向量化与线程级并行性不同。向量化试图通过尽可能多地使用更多矢量通道来提高性能。向量通道在单个处理器内核上运行的每个线程之上提供了额外的并行性。向量化的目的是最大程度地利用每个内核的可用向量寄存器。
从技术上讲,历史上的向量处理体系结构被认为与SIMD体系结构是分开的。如上的观点基于如下的事实:向量机用于通过流水线处理器一次处理一个单词(尽管仍然基于单个指令),而现代SIMD机却同时处理向量的所有元素。但是,如今,具有SIMD处理功能的许多计算单元在硬件级别可用,并且向量处理器实质上是SIMD处理器的同义词。在过去的几十年中,每个处理器内核中都有越来越广泛的向量寄存器可用于向量化:例如,奔腾中的64位MMX寄存器支持MMX扩展,奔腾IV中的128位XMM寄存器支持SSE和SSE2扩展,第二代Core处理器中的256位YMM寄存器以支持AVX和AVX2扩展,Xeon Phi协处理器中的512位ZMM寄存器支持MIC扩展。对于数据并行的应用(例如视频编码)而言,这些宽向量寄存器非常有用。
常规编程语言因其固有的串行特性而受到限制,并且不支持SIMD处理器提供的计算功能。因此,需要扩展常规编程语言才能利用这些功能。为此,开发了串行代码的向量化和向量编程模型。例如,OpenMP 4.0支持C/C++和FORTRAN的向量编程模型,并提供语言扩展以简化向量编程,从而使开发人员能够从SIMD处理器中优化更多性能。英特尔Click Plus是另一个支持类似语言扩展的示例。
自动向量化过程会在给定其串行约束的情况下尝试对程序进行向量化处理,但却未充分利用可用的计算能力。随着向量宽度和核数的增加,英特尔开发了明确的方法来应对这一趋势。随着现代CPU中集成显卡和协处理器的应用,具有显式向量编程功能的通用编程模型被添加到诸如Intel编译器,GCC和LLVM的编译器中,以及OpenMP 4.0等标准中。该方法类似于多线程,解决了多个内核的可用性并使这些内核上的程序并行化。向量化还通过显式向量编程解决了增加向量宽度的可用性。
向量化在视频编码性能优化中很有用,尤其是对于基于CPU的软件实现而言。像素数据长度为16个元素的向量可以在关键循环内提供高达16倍的速度提升,例如,用于运动估计,预测,变换和量化操作。在诸如视频转码的应用中,某些视频处理任务(例如降噪)可以利用视频数据的易于向量化的结构来并提高速度。