明确的向量化
Explicit vectorization
本文关键字:向量化 更新时间:2023-10-16
据我所知,如果设置相应的编译器标志,大多数现代编译器会在适当的地方自动使用SIMD循环指令。因为编译器只能使用向量化,如果它可以确定这样做不会改变程序的语义,它不会使用向量化的情况下,我实际上知道它是安全的,但编译器出于各种原因认为它不是。
是否有明确的向量化指令,我可以在没有库的普通c++中使用,这让我自己处理向量化数据,而不是依赖编译器?我想象它看起来像这样:
double* dest;
const double* src1, src2;
// ...
for (uint32 i = 0; i < n; i += vectorization_size / sizeof(double))
{
vectorized_add(&dest[i], &src1[i], &src2[i]);
}
普通c++ ?不。std::valarray
可以引导你的编译器到SIMD水,但不能让它喝水。
OpenMP是最小的"库"库:与其说它是一个库,不如说是一个语言扩展,所有主要的c++编译器都支持它。虽然OpenMP 4.0主要用于多核并行,但它引入了特定于simd的构造,这些构造至少可以促使编译器对某些明显可向量化的过程进行向量化,即使是那些具有明显标量子例程的过程。它还可以帮助您识别阻止编译器向量化的代码方面。(除此之外…难道你不也想要多核并行吗?)
double* dest;
const double* src1, src2;
#pragma omp simd
for (int i = 0; i < n; i++)
{
dest[i] = src1[i] + src2[i];
}
为了完成最后一英里的低精度操作,多通道聚合,无分支屏蔽等,确实需要显式连接到底层指令集,这是不可能的任何接近"普通c++"。不过,OpenMP可以让你走得更远。
TL;DR不能保证,但是KISS和您可能会得到高度优化的代码。在修改生成的代码之前,对其进行测量和检查。
你可以在在线编译器上使用它,例如gcc。godbolt将用-O3
向量化gcc 5.2中对std::transform
的直接调用#include <algorithm>
const int sz = 1024;
void f(double* src1, double* src2, double* dest)
{
std::transform(src1 + 0, src1 + sz, src2, dest,
[](double lhs, double rhs){
return lhs + rhs;
});
}
本周早些时候有一个类似的问题。总的主题似乎是,在现代处理器和编译器上,代码越直接(普通算法调用),就越有可能得到高度优化(矢量化、展开)的代码。
相关文章:
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- Android NDK传感器向事件队列报告奇怪的间隔
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 普通环路未使用gcc 4.8.5自动矢量化
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- Visual Studio 2017循环自动向量化问题
- NEON向量化无符号字节积和:(a[i]-int1) * (b[i]-int2)
- 为什么GCC不自动向量化这个循环?
- 明确的向量化
- 英特尔编译器不能向量化这个简单的循环
- 用特征向量化表达式
- 对于小型查找表,表查找是可向量化的
- 向量化(SIMD)树操作
- 优化向量化嵌套循环
- 向量化短到浮点的转换
- 需要帮助向量化此代码
- 重叠数组的和,自动向量化,和限制
- 如何使GCC向量化此循环