使用SSE和STL矢量计算平均值
Calculate average using SSE with STL vectors
我正在尝试学习矢量化,而不是重新检查轮子,我正在使用Agner Fog的矢量库
这是我的原始C++/STL代码
#include <vector>
#include <vectorclass.h>
template<typename T>
double mean_v1(T begin,T end) {
float mean = 0;
std::for_each(begin,end,[&mean](const double& d) { mean+=d; });
return mean / std::distance(begin,end);
}
double mean_v2(T begin,T end) {
float mean = 0;
const int distance = std::distance(begin,end); // This is expensive
const int loop = ( distance >> 2)+1; // divide by 4
const int partial = distance & 2; // remainder 4
Vec4d vec;
for(int i = 0; i < loop;++i) {
if(i == (loop-1)) {
vec.load_partial(partial,&*begin);
mean = horizontal_add(vec);
}
else {
vec.load(&*begin);
mean = horizontal_add(vec);
begin+=4; // This is expensive
}
}
return mean / distance;
}
int main(int argc,char**argv) {
using namespace boost::assign;
std::vector<float> numbers;
// Note 13 numbers, which won't fit into a sse register perfectly
numbers+=39.57,39.57,39.604,39.58,39.61,31.669,31.669,31.669,31.65,32.09,33.54,32.46,33.45;
const float mean1 = mean_v1(numbers.begin(),numbers.end());
const float mean2 = mean_v2(numbers.begin(),numbers.end());
return 0;
}
v1和v2都能正常工作,而且它们所花费的时间大致相同。然而,分析它显示std::distance(),并且移动迭代器几乎需要总时间的45%。矢量相加仅为0.8%,明显快于v1。
在网络上搜索,所有的例子似乎都处理了完美数量的值,这些值正好适合SSE寄存器。人们如何处理奇数值?例如,在这个例子中,设置循环所花费的时间比计算要长得多。
我认为必须有关于如何应对这种情况的最佳实践或想法。
假设我不能将mean()的接口更改为float[],但必须使用迭代器
您正在混合float&加倍是不必要的,尤其是当你不让你的累加器加倍时,你的精度会被完全破坏,对于更大的系列来说,这不会令人满意。
由于算法的重量非常轻,在这里破坏性能的很可能是内存访问、对内存缓存线的读取以及它们的工作方式。基本上,您在这里需要做的是提前探测,一些处理器有明确的指令将内容拉入缓存,否则您可以提前在内存位置执行加载。在循环中创建另一个级别的嵌套,并定期用您知道在几次迭代中会得到的数据填充缓存。
为了最大限度地提高性能,人们需要花费大量时间来实际设计数据布局。您不需要对数据进行中间转换。因此,人们所做的是分配对齐的内存(大多数SIMD指令集要求或对读取/写入未对齐的内存施加严重惩罚),然后他们试图以适合指令集的方式聚合数据。事实上,将数据填充到指令集支持的任何寄存器大小通常都是一种胜利。所以,如果假设你要处理三维向量,那么用一个未使用的额外元素填充几乎总是一个巨大的胜利。
相关文章:
- 计算平均值,不包括上次得分
- 在二叉搜索树C++中计算平均值
- 计算平均值:蒙版图像与投资回报率的不同结果
- 类型检测:使用variadic参数正确实现计算平均值的函数
- C 平均程序在循环时不计算n后不计算平均值
- 我必须将 5 个数字放入一个数组中,而不是 cin 计算平均值并输出它,我做错了
- 我需要知道如何正确计算平均值和偏差
- 从数组中获取值并计算平均值,然后存储在数组中
- 发布获取语义以计算平均值
- 计算平均值,而不向退出循环添加负等级
- 如何正确使用指针来计算平均值
- 如何计算平均值
- 在没有值时跳过计算平均值.C++.Xcode
- 用c++计算平均值和方差
- 用于计算平均值的C++程序
- 高精度计算平均值的最佳策略
- 计算平均值C++
- 程序不会降低最低分数并在没有它的情况下计算平均值
- 我需要将Valus与字符串关联的帮助才能计算平均值
- 如何使用 std::累积 和 lambda 来计算平均值