【发布时间】:2016-05-03 05:41:11
【问题描述】:
英特尔编译器允许我们通过以下方式对循环进行矢量化
#pragma simd
for ( ... )
但是,您也可以选择使用 OpenMP 4 的指令来执行此操作:
#pragma omp simd
for ( ... )
这两者有区别吗?
【问题讨论】:
标签: openmp vectorization simd
英特尔编译器允许我们通过以下方式对循环进行矢量化
#pragma simd
for ( ... )
但是,您也可以选择使用 OpenMP 4 的指令来执行此操作:
#pragma omp simd
for ( ... )
这两者有区别吗?
【问题讨论】:
标签: openmp vectorization simd
#pragma simd
- 被定位为英特尔 C++ Cilk SIMD 扩展的一部分(连同 Array Notation)。这种定位看起来有点奇怪,因为 Cilk 不适用于 Fortran,而 Fortran Compiler 支持几乎相同的指令 simd。
#pragma omp simd
- 是 OpenMP 标准的一部分,因此它自然更易于跨编译器和平台移植。
通常,英特尔首先在 Cilk 中推出新功能,然后在 OpenMP 中推出。原因很自然:接受某些东西作为 OpenMP 标准的一部分需要时间。例如,simdlen 仅在 2015 年 11 月添加到 OpenMP4.5 中,而相同的子句 (vectorlength) 已经在 3 或 4 年前成为 Cilk pragma 的一部分。 simdlen vs. vectorlength 突出了另一个观察结果,即 simd 和 omp simd 之间的某些 pragma 子句语法可能不同。
因此,如果您需要跨编译器的可移植性,请使用 OpenMP pragma。但是,如果尽早访问新的 simd 编译器功能对您来说更重要,那么您可能更喜欢或可选地使用 Cilk(专有)编译指示。所有相同的论点和注意事项同样适用于#pragma omp declare simd vs. #pragma declare simd(应该回答您可能的第二个问题)。
此处提供“Cilk”编译指示 simd 子句的参考:https://software.intel.com/en-us/node/524555 (我认为它有点过时了;我听说过 pragma simd 的新功能尚未反映在此链接中)。
【讨论】:
#pragma omp simd的解释吗?
出于所有意图和目的,它们应该是相同的。不同之处在于 OpenMP 4.0 #pragma omp simd 指令是可移植的,应该可以与支持 OpenMP 4.0 以及 Intel 的其他编译器一起使用。
此外,OpenMP 版本中有几个子句允许您以更健壮的方式对指令进行矢量化(safelen()、linear()、aligned()、reduction() 和 collapse() 浮现在脑海中)。
【讨论】:
aligned 是一个不错的功能,因为 ICC 和 GCC 也有不同的内置函数来执行此操作,但使用相同的语法来执行此操作更方便。 Clang 使用与 GCC 相同的内置函数,因此如果 Clang 支持 OpenMP 4.0,那么所有三个编译器都会有一种语法,这显然更方便。但是,MSVC 可能永远不会支持 OpenMP 4.0(以及 3.0),但我不知道有任何类型的 MSVC 对齐的 buliitin。
aligned 和 omp simd 所做的。它不对齐内存,它告诉编译器假设它是对齐的。