【问题标题】:Vectorize function calls on each element of a vectorVectorize 函数调用向量的每个元素
【发布时间】:2015-07-23 00:42:43
【问题描述】:

当我们使用 for_each 为向量中的每个元素调用函数时,调用是否已向量化?

【问题讨论】:

  • 什么是向量化调用?你是在问for_each 是否使用多线程?
  • 你指的是SIMD指令吗?
  • 例如,我在函数中将元素递增 5
  • 实验上,答案是“也许”。所以不能笼统地回答。如果它是“不,从不”,那将是一个答案,但在某些情况下,一些编译器会这样做 (proof)。

标签: c++ optimization vector vectorization


【解决方案1】:

一般来说不会。

std::for_each 只是一个循环的包装器。

但是,通过优化,对std::for_each 的调用很可能是内联的,对于简单的函数,每个元素的函数调用也可能是内联的。

一旦内联了所有内容,就好像循环是手工编写的;在这种情况下,问题就变成了“编译器会向量化一个循环做简单的算术吗”;这完全取决于编译器。

为了实现这一点,编译器需要知道目标架构支持 SIMD 指令,并且可能会或可能不会向量化,具体取决于优化级别、迭代次数是否恒定、迭代次数是否已知是 4 的倍数,等等。

【讨论】:

  • 进一步概括:如果函数调用没有内联,仍然可以通过在函数声明上使用#pragma omp declare simd 来向量化此类循环——这也称为“启用 SIMD 的函数”技术。不幸的是,这种技术仅适用于某些版本的英特尔编译器或支持 OpenMP4.0 标准的编译器。
【解决方案2】:

假设您询问的是 std::vector,答案是否定的。 std::vector 是数组的包装器,但它间接访问这些内存块。但是,您可以像 myVec.begin()._Ptr 那样获取行指针并在循环中使用它。使用 noalias 声明方法会有所帮助,例如 __declspec(noalias)。问题的第二部分由卡梅伦回答。如果函数被内联并且架构支持矢量化数据,编译器现在应该对数据进行矢量化。

【讨论】:

  • 所有这些都是完全特定于平台的。而且是不必要的。你可以只做&myVec[0],保证可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-28
  • 2022-11-02
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多