我有一个使用 Clang 编译器在
-mavx/-mavx2
标志下编译的 C++ 源文件。
有些函数有 AVX2 实现,但有些只是纯粹的 std 调用。
我想知道
std::sort
(1)、std::memcpy
(2) 和 std::accumulate
是否可以因为 -mavx
标志而被矢量化?因此,删除该标志可能会影响这些函数的性能。谢谢。
是的,他们都可以。但细节有所不同。
memcpy
、memmove
和memset
函数作为C标准库的一部分实现,它是单独预编译的静态或共享库。那里的实现应该已经矢量化了。然而,编译器知道它们的语义,并且可以用内联实现替换对 C 标准库的调用,如果矢量化适用,则进行矢量化。
当预先知道大小时,用内联实现替换
memcpy
特别有用。在这种情况下,内联实现肯定会优于库实现,即使库实现是矢量化的,因为知道大小是一个很大的好处。
对于非常小的已知大小,没有什么可以矢量化,这只是通用寄存器的移动。对于中等尺寸,这将被矢量化并展开。最后,对于大尺寸,编译器可能决定调用 C 标准库实现,因为内联库实现也不会好多少。
像
std::accumulate
、reduce
或inner_product
这样的算法是模板化的,因此它们没有预编译的实现。通常使用纯数据类型并且没有可疑的别名编译器会完美地自动向量化它们。
对于更复杂的算法,编译器可能没有足够的能力来自动向量化它们。在这种情况下,STL 实现可能仍然专门用于对它们进行矢量化。例如,最近在 STL 中添加了手动矢量化,例如
libc++和 MSVC STL 中的
mismatch
。
std::sort
是最复杂的之一,但仍然可以矢量化。检查您的 STL 实现或编译器输出。