关于IPP 矩阵乘法的performance的一点研究

Intel_huGh 2008-07-08 09:54:47
在前面的帖子中,youxia000提出了Ippmul_mv_64f的效率问题研究。针对他的问题,我做了一系列的测试。
下面我将列出我的一些测试结果,权当抛砖引玉。

测试代码:
我主要测试了4种代码,都是实现矩阵与向量的乘法,矩阵的大小都是4×4,向量为4×1,由于单次运算时间较短,我让每种运算都循环执行1000000 次。

代码段中,a是矩阵,b是向量,矩阵a可以用二维数组或者一维数组表达

1) a是二维数组
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
result[j] += b[k] * a[j][k];

2> a是一维数组
for (i = 0; i < N; i++) {
for (j=0; j<N; j++) {
result[i] += a[N*i+j] * b[j];
}
}

3> a是二维数组,同时将<1>中的for循环展开
Result[0] = b[0] * a[0][0] + b[1] * a[0][1] + b[2] * a[0][2] + b[3] * a[0][3];
Result[1] = b[0] * a[1][0] + b[1] * a[1][1] + b[2] * a[1][2] + b[3] * a[1][3];
Result[2] = b[0] * a[2][0] + b[1] * a[2][1] + b[2] * a[2][2] + b[3] * a[2][3];
Result[3] = b[0] * a[3][0] + b[1] * a[3][1] + b[2] * a[3][2] + b[3] * a[3][3];

4>IPP实现mv乘法,IPP中a只能是一维数组
IppStatus status = ippmMul_mv_64f((const Ipp64f*) a, src1Stride1, src1Stride2,
src1Width, src1Height, (const Ipp64f*) b, src2Stride2,
src2Len, result, dstStride2);
...全文
575 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
intel_iclifort 2011-11-10
  • 打赏
  • 举报
回复
不错的文章,旧帖重温,顶一下
chenxiaojuan_1208 2009-12-10
  • 打赏
  • 举报
回复
xuexi
Intel_huGh 2008-07-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Intel_huGh 的回复:]
引用 5 楼 youxia000 的回复:
Method Time (seconds)
1 0.506967
2 1.34616
3 0.0464487
4 0.226544

把楼主的结果重新排列了下,

类似的测试我在 我的那个帖子里也贴过,

不同的地方是 我是用结果Result 赋给 b 在进行下一次的循环 且 我做的是 3维的坐标旋转 只有 3*3 和 3*1 来做乘法 要小一些

我想不太明白为什么 你测试的 1, 2 会比4 慢哪…
[/Quote]
生成的obj文件和最后的可执行文件,补充下,呵呵
Intel_huGh 2008-07-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 youxia000 的回复:]
Method Time (seconds)
1 0.506967
2 1.34616
3 0.0464487
4 0.226544

把楼主的结果重新排列了下,

类似的测试我在 我的那个帖子里也贴过,

不同的地方是 我是用结果Result 赋给 b 在进行下一次的循环 且 我做的是 3维的坐标旋转 只有 3*3 和 3*1 来做乘法 要小一些

我想不太明白为什么 你测试的 1, 2 会比4 慢哪么多 而且 1,2 差的好多啊

[/Quote]
大维度的 矩阵 * 向量可以在编译选项中展开循环来提高速度 linux下的 -funroll-loops, intel compiler(icl)使用的 -O3 and/or -/Qxp都可以在编译的时候展开循环,但是这样的一个很大的弊端就是会是代码变大,特别是大维度的循环。
youxia000 2008-07-23
  • 打赏
  • 举报
回复
呵呵,非常感谢你们把这个问题证明了,

学习
youxia000 2008-07-23
  • 打赏
  • 举报
回复
Method Time (seconds)
1 0.506967
2 1.34616
3 0.0464487
4 0.226544

把楼主的结果重新排列了下,

类似的测试我在 我的那个帖子里也贴过,

不同的地方是 我是用结果Result 赋给 b 在进行下一次的循环 且 我做的是 3维的坐标旋转 只有 3*3 和 3*1 来做乘法 要小一些

我想不太明白为什么 你测试的 1, 2 会比4 慢哪么多 而且 1,2 差的好多啊

ipp在做大维度的 矩阵 * 向量 会能接近 3的结果吧,比如10维的乘法 一个一个写就太恐怖了 若是矩阵*矩阵的 还是用ipp好


Intel_merryhy 2008-07-08
  • 打赏
  • 举报
回复
有道理! 可以细说一下这里的时间测试是用的什么函数?还有编译器是什么版本,需要做特别的编译选项设置吗?
Intel_huGh 2008-07-08
  • 打赏
  • 举报
回复
补充下,我的机器配置是
Intel Pentium M 1.86G
1G的内存
Intel_huGh 2008-07-08
  • 打赏
  • 举报
回复
结果分析:
通过时间大小分析,我们可以看到,使用二维数组表示矩阵可以提高performance,这是因为使用一维表达的话,每次我们取数时,都需要计算数组的index。

同时,展开for loop可以提高performance,但是在大循环的情况下,展开for循环是不切实际的,因为一方面书写问题,另一方面,完全展开,将会导致编译出的二进制代码很大。




优化注意事项


即使不是专门针对英特尔微处理器的优化,英特尔编译器也有可能无法为非英特尔微处理器实现相同程度的优化。这些优化包括 SSE2、SSE3 和SSSE3 指令集和其他优化。 英特尔不保证任何优化在非英特尔制造的微处理器上的可用性、功能或有效性。本产品中依赖于微处理器的优化旨在配合英特尔微处理器一起使用。不一定针对英特尔微架构的某些优化专为英特尔微处理器保留。请参见适用产品的“用户和参考指南”了解本注意事项中涵盖的特定指令集的更多相关信息。


注意事项修订版 #20110804

Intel_huGh 2008-07-08
  • 打赏
  • 举报
回复
测试结果:
Method 1 2 3 4
Time (seconds) 0.506967 1.34616 0.0464487 0.226544

消耗的时间: 展开for循环,同时二维数组表达 < IPP < 二维数组表达,但是不展开for循环 < 一维数组表达,同时不展开for
[3] < [4] < [1] < [2]

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧