非常基本的SSE
Really basic SSE
我有一个非常简单的程序,我试图提高性能。我知道的一种方法是利用SSE3(因为我正在工作的机器支持这个),但我完全不知道如何做到这一点。下面是一个代码片段(c++):
int sum1, sum2, sum3, sum4;
for (int i=0; i<length; i+=4) {
for (int j=0; j<length; j+=4) {
sum1 = sum1 + input->value[i][j];
sum2 = sum2 + input->value[i+1][j+1];
sum3 = sum3 + input->value[i+2][j+3];
sum4 = sum4 + input->value[i+3][j+4];
{
}
我读了一些关于这个的东西,并且理解了这个想法,但是我完全不知道如何实现它。有人能帮帮我吗?我认为这是相当简单的,特别是对于我的简单程序,但有时开始是最难的部分。
谢谢!
实际上,在您的情况下,事情并没有那么简单。现在,你的代码是NOT可矢量化的。(至少没有重要的循环转换)
这样做的原因是您在内部循环中也更改了索引i
。由于内存位置不再相邻并且位于矩阵的不同行,因此中断了能够对j
迭代进行矢量化的任何机会。(因为你似乎在对角线上运行矩阵)
然而,我得到的感觉是,你试图总结你的矩阵中的所有元素,你实际上打算你的循环是这样的(你也有一些错字):
int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i=0; i<length; i++) {
for (int j=0; j<length; j+=4) {
sum1 = sum1 + input->value[i][j];
sum2 = sum2 + input->value[i][j+1];
sum3 = sum3 + input->value[i][j+2];
sum4 = sum4 + input->value[i][j+3];
}
}
int total = sum1 + sum2 + sum3 + sum4;
如果这是你想要的,那么它是非常可矢量化的。在使用内部函数的C/c++中,只需使用SSE2就可以这样做:
__m128i sum = _mm_setzero_si128();
for (int i=0; i<length; i++) {
for (int j=0; j<length; j+=4) {
__m128i val = _mm_load_si128(&input->value[i][j]);
sum = _mm_add_epi32(sum,val);
}
}
注意对齐限制将被应用。通过进一步展开循环,可以获得更多的加速。
相关文章:
- OpenGL大的3D纹理(>2GB)非常慢
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- 使用浮点数和双精度数的非常小数字的数学
- 在打开多个其他窗口时使用全屏窗口时帧速率非常低
- C++ SSE 内部函数:将结果存储在变量中
- 我从int x[3]得到的一个非常奇怪的输出;
- 反向迭代器在C++中非常奇怪的行为
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 我的自定义使用 std::unordered_map 的性能非常慢
- ifstream 尝试读取 9 到 13 之间的无符号字符时非常奇怪的行为
- 一个非常简单的win32套接字代码,但工作错误
- 非常快速地阅读 CSV 文件
- max_element() 给出非常奇怪的错误消息
- 将 mmap 内存用于开销非常低的循环缓冲区
- Constexpr and SSE intrinsics
- 如何使用SSE将__m128i注册乘以浮点因子?
- 内存映射文件访问非常慢
- 非常基本的SSE