「C++」指令集优化-CPU上矩阵点积计算效率立即提升30%

「C++」指令集优化-CPU上矩阵点积计算效率立即提升30%

编码文章call10242024-12-13 11:57:3325A+A-

指令集,可以直接控制CPU内寄存器,累加器的指令集合。一般寄存器需要写汇编控制的,但是有些c/c++函数库包装了指令集,所以也可以在c/c++中调用指令集。

在计算机中执行计算任务,使用在指令层面进行优化,算法比较底层了,

指令集优化在一些开源的快速的计算库中已有实现,比如opencv中,它的指令集优化做得非常好,一般写指令集优化程序都干不过它。

比如一个乘法,如果你优化的能够超过opencv,那也算比较厉害了。

除了opencv,像我们常用的pytorch,caffe2,tensorflow都在指令集优化方面有所设计,或者包含已有的指令集优化库,或者自己开发。

我们落地人工智能项目的过程中,指令集优化是最基础的工作,难度大,但是一旦完成优化,在当前cpu你可以做到更快。


cpu与指令集

由于要使用汇编操作cpu内部的寄存器,所以不同cpu对应的 指令集是不同的。

Inter的cpu,AMD的cpu,arm等的指令集都不同。

随着时间的发展,指令集也在发展,所有同一种cpu上,支持的指令集也在不断地完善,同一种cpu上会支持很多个版本的指令集,也支持很多种的指令集。

那么如何查看你电脑上的cpu支持哪些指令集呢?

查看苹果支持的指令集:


可以看到,我的电脑上,cpu是 Intel的,指令集支持SSE4.2,AVX等常用的Intel指令集。

查看linux上cpu所支持的指令集,用:cat /proc/cpuinfo

查看windows上的cpu所支持的指令集用: cpu-z

样例

下面我们就写一个小程序,把乘法用指令集来完成,并与默认的乘法符号做了对比,发现性能有大约30%左右的提升,真是没想到。如下图


全部代码在:https://gitee.com/anjiang2020_admin/cpp_exp/blob/master/15_zlj.cc

下面看一下重点代码。

首先是普通的for循环做矩阵点积的计算:


然后是使用SSE指令集的intrinsic函数进行计算:


第70行的_mm_load_ps函数,将4个32个字节float型数据装入cpu内部寄存器,因为寄存器是128位的,所以一次可装入4个单精度的float类型数据,__m128是一个结构体,其中有个float类型的长度为4的数组,刚好128位,所以起名__m128。

第71行也一样,把pb所指的128 字节的数据装入cpu的寄存器中

第72行就是真正的计算了,将寄存器中的数据,sse_1 和sse_2对应位置相乘,结果放入h中。这就实现了一次计算4个float 类型数据的相乘。

第73行将寄存器中的数据h存放回pa中。

注意到,这里先使用了load函数,将数据从内存加载入寄存器中,mul计算完成后,然后将结果用store函数从寄存器送到了内存中。数据存储位置的流转如下:


关于指令集的intrinsic,还有一些细节要注意:

_mm_load_ps函数,

有一个对应的函数_mm_loadr_ps,多了一个字母r,就是把4个float数据反向装入寄存器中的意思

还有一个对应的函数_mm_load_ss,就是只操作4个float中的第一个的意思。s:表示对一个scaler标量的处理。p表示打包package处理,对向量中所有的值都处理,这里向量长度为4.

更多细节可以参考后面的参考文献,写得非常好。

另外这里在C++中调用了指令集的intrinsic函数,其实原本的指令集是汇编语言,intrinsic函数就是包裹了汇编语言的库,引用如头文件即可使用:


当然,也可以在C/C++代码中,插入汇编语句进行操作。


总结一下指令集优化的思路:

1 利用寄存器的长度128,一次性计算4个float数据,实现并行计算。寄存器长度为512时,并行程度就更好了。

2 并行程度高以后,我们就是要优化依赖关系了,比如深度学习模型的前向计算过程,层与层之间是有依赖关系的,被依赖的层必须首先计算出结果。那么如何减少等待时间就是我们优化的方向:要估计出每个神经元节点的计算耗时,合理优化不同节点的计算顺序。

3 我们把总的计算流程称为计算树。由于不同的cpu的指令集不同,运算时间不同,计算树的具体优化动作就会不同。

在pytroch的源码中,就有计算中的依赖关系的设计,个人在部署的时候,可以参考pytorch的源码,具体位置在:


当然,pytorch也使用了指令集去进行优化:





pytorch也是按照数据先装载load进入寄存器在计算,计算完需要将数据store处理的流程进行指令集优化的。


参考:

  1. https://blog.csdn.net/myhes/article/details/110258396
  2. https://blog.csdn.net/qq_27825451/article/details/103934359
点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4