提问者:小点点

long double数据类型上的openMP矢量化运算是不可能的吗?


我正在学习openMP,用我有限的知识,并行化了我的代码。我正试图使用openMP矢量化技术来改进这段代码。但是在浏览相关阅读材料时,我发现对long double数据类型进行矢量化运算是不可能的。有人能提供为什么会这样的信息,并提出除了降低精度以外的解决方案吗?

链接中的内容如下:“避免SIMD硬件不支持的操作。(80位)长的算术在Linux上加倍,余数运算符“%”是SIMD硬件不支持的操作示例。”

注:我使用的是INTEL C编译器16.0.2、带128位长矢量寄存器的INTEL XEON处理器和Linux。我的数据类型大多是长双精度的。


共1个答案

匿名用户

x86指令集的SIMD指令仅支持32位和64位浮点运算(对16位浮点数的支持有限)。此外,即使有64位乘以64位到128位标量整数指令(例如Mulx),也没有相应的SIMD指令。许多人尝试过但未能实现高效的128位整数x86 SIMD算术(乘法和加法有一些例外)。没有通用的x86 SIMD整数除法指令。

但是,对于浮点数,人们使用双精度运算进行更高精度的浮点 SIMD 运算取得了更大的成功。双精度具有 106 位精度,而 64 位精度为 80 位长双精度。但并非每个 C 编译器都使用 80 位长双精度。有些只使用只有54位精度的双精度(例如MSVC),有些使用128位四精度,精度为113位,维基百科甚至声称在一些编译器中,长双精度被实现为双精度。

我在这里描述了双双的一些细节。注意,doubledouble不是IEEE浮点类型,它具有一些不寻常的属性。此外,double double的范围与double相同,因此它只会提高精度。

与长双精度相比,双精度的速度有多快?我从来没有测试过这个。但是我发现,当进行乘法和加法运算的平衡混合时,双精度比双精度运算慢10倍左右。长双精度肯定比双精度慢(除非它是作为双精度实现的)。但是,由于您可以将SIMD与双精度一起使用,但不能与内置的长双精度一起使用,因此速度与SIMD宽度成比例地提高。因此,SSE2使用2次双精度运算,AVX使用4次,AVX512使用8次。

不过,不要期望OpenMP的simd构造能够实现双精度。您需要自己实现或找到一个库。