优化的 SIMD 矢量库无法通过等效标量运算执行
Optimized SIMD vector library is out performed by equivalent scalar operations?
我编写此代码是为了测试特征加法与普通旧标量加法的性能。
int x, y;
cin >> x; cin >> y;
typedef int theType;
Array<theType, 8, 1> theArray; theArray << 0,0,0,0,0,0,0,0;
StopWatch sw;
sw.Start();
for(int k = 0; k < y*1000000; k++){
theArray << 0,0,0,0,0,0,0,0;
for (int i = 0; i < 10 *x; i++){
theArray += 2;
}
}
sw.Stop();
cout << theArray << " : " << sw.MilliSeconds() << endl;
theType f = 0;
sw.Start();
for(int k = 0; k < y*1000000; k++){
f = f-1;
for (int i = 0; i < 80 * x; i++){
f += 2;
}
}
sw.Stop();
cout << f << " : " << sw.MilliSeconds();
我正在使用 g++ -O2 运行该代码。我用命令行设置 x 和 y,并将它们用作 for 循环中的上限,这样编译器就不会优化 for 循环。特征测试生成一个包含 8 个值的数组,并添加一个常量分量。标量测试只是递增一个标量值,但它的完成量是特征测试的 8 倍。
结果(使用 x = 1,y=1):
使用 int 作为类型:52
毫秒特征与 1 毫秒标量使用 short 作为类型:54 毫秒特征与 1 毫秒标量
为什么本征速度较慢?由于在本征中使用了 SIMD,我预计它会更快一些。本征真的这么慢,还是我做错了什么?
你的内心循环:
for (int i = 0; i < 80 * x; i++){
f += 2;
}
被编译器优化掉。在 x86 的 VC++ 上编译时,整个循环折叠成一条汇编指令:
lea esi, DWORD PTR [esi+ecx*2]
其中ecx
是 80*x 的值,esi
是f
变量的值。
您将需要某种方法来禁用循环优化。除此之外,在单个标量上执行 8 个操作总是比在 8 个元素的数组上执行一个操作更快,因此我建议将f
变量转换为数组f[8]
,以实现与矢量码的奇偶校验。完成此操作后,您会发现特征码明显比非矢量化代码快。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 我可以强制执行标量类型通过 int{} 初始化为零吗?
- 优化的 SIMD 矢量库无法通过等效标量运算执行