【问题标题】:Is openMP vectorization operations on long double datatype not possible?是否不可能对 long double 数据类型进行 openMP 矢量化操作?
【发布时间】:2016-05-09 07:07:13
【问题描述】:

我正在学习 openMP,但我的知识有限,我的代码已并行化。我正在尝试使用 openMP 矢量化技术改进此代码。但是在阅读相关阅读材料(link)时,我发现不可能对 long double 数据类型进行矢量化操作。有人可以提供有关为什么会这样的信息并提出解决方案而不是降低精度吗?

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

附:我正在使用 INTEL C++ 编译器 16.0.2、带有 128 位长向量寄存器和 Linux 的 INTEL XEON 处理器。我的数据类型大多是 long double。

【问题讨论】:

  • 我认为您将并行性与矢量内在混淆了。我怀疑可以并行化这些操作,即使它们没有映射到英特尔的 ISA。无论如何,您需要发布一个完整的、可运行的示例。
  • 因为 x86 SIMD 硬件(SSE 到 AVX512)仅支持 32 位和 64 位浮点运算,并且没有整数除法指令。
  • 你为什么使用 long double?
  • @Zboson 我正在开发 CFD 求解器。为了确保方案的数值稳定性,我们需要良好的精度。这就是为什么。
  • @prasanna:只有 54 位精度才能变得稳定的算法非常少,而那些很少会被简单地转换为使用较少位即可稳定的等效算法。如果您有更高的精度,您可能会发现迭代解决方案在更少的步骤中收敛,这是真正的好处,但是当每个更高的精度步骤更慢时,您会再次失去它。所以 64 位双精度可能是最快的。

标签: c++ parallel-processing x86 openmp sse


【解决方案1】:

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

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

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

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

不要指望 OpenMP 的 simd 构造实现双双。您需要自己实现它或找到一个库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多