OpenBlas单精度点积-cblas_sdot
一、交叉编译
由于要在海思平台处理大量浮点数据,测试过程中,发现使用cpu计算,速度跟不上,遂思考需求加速的办法,开始考虑移植caffe到海思平台使用cuda加速,但是移植过程比较麻烦,放弃了。最后决定单独编译使用OpenBlas来加速计算,这个库是我们国内牛人张博士大神写的开源库现已被广泛应用。废话不多说,老规矩先上源码链接:https://github.com/xianyi/OpenBLAS
下载源码解压,接下来我们要进行交叉编译。进入源码目录。
首先修改Makefile.arm文件(要根据自己是64还是32位平台进行选择修改),我这里的平台是Hisi3516:
接下来进行编译:
make TARGET=ARMV7 BINARY=32 HOSTCC=gcc CC=arm-himix200-linux-gcc NOFORTRAN=1 libs shared
编译前可看看wiki,简单解释下个参数的意思:
TARGET=ARMV7 指定cpu架构
BINARY=32 指定平台是32和64位
HOSTCC=gcc 指定编译主机使用的编译器
CC=arm-himix200-linux-gcc 指定交叉编译使用的编译器
NOFORTRAN=1 指定不使用fortran语言版本
libs shared 指定生成动态共享库
有些参数不指定的会自动侦测,但是最好指定以防错误。
编译成功后把库和头文件拷贝到开发板以便使用。
二、使用测试
本实例中不再展示使用普通方法cpu计算过程,此种方法同样2万数据量需要1.5s左右,这里我们着重介绍openblas的使用:
int main()
{
float A[8] = {-0.10439769178628922, -0.02082710899412632, 0.030702540650963783, 0.03613700345158577,
0.10332922637462616, 0.0828862339258194, 0.09160517901182175, -0.155189648270607};
float B[8] = {-0.11439769178628921, -0.05082710899412632, 0.040702540650963783, 0.03613700345158577,
0.10332922637462616, 0.0828862339258194, 0.09160517901182175, -0.155189648270607};
QTime tt;
tt.start();
for(int i=0;i<20000;i++)
{
//分别计算A*B,A*A,B*B
float resultA_B = cblas_sdot((blasint)8,A, 1, B, 1);
float resultA_A = cblas_sdot((blasint)8,A, 1, A, 1);
float resultB_B = cblas_sdot((blasint)8,B, 1, B, 1);
}
qDebug()<<"Oh!===it take time:"<<tt.elapsed();
return 0;
}
测试结果令人满意,处理2万条数据只使用了50ms,相对于没有使用加速库之前,仅仅花费了原来的1/30的时间。
接下来我们再来看看
n:向量中元素个数, incx,incy:下标增量
//计算两个单精度向量与一个初始单精度值的点积。
float cblas_sdsdot(OPENBLAS_CONST blasint n, OPENBLAS_CONST float alpha, OPENBLAS_CONST float *x, OPENBLAS_CONST blasint incx, OPENBLAS_CONST float *y, OPENBLAS_CONST blasint incy);
//计算一对单精度的双精度点积
double cblas_dsdot (OPENBLAS_CONST blasint n, OPENBLAS_CONST float *x, OPENBLAS_CONST blasint incx, OPENBLAS_CONST float *y, OPENBLAS_CONST blasint incy);
//计算俩个单精度点积
float cblas_sdot(OPENBLAS_CONST blasint n, OPENBLAS_CONST float *x, OPENBLAS_CONST blasint incx, OPENBLAS_CONST float *y, OPENBLAS_CONST blasint incy);
//计算俩个双精度点积
double cblas_ddot(OPENBLAS_CONST blasint n, OPENBLAS_CONST double *x, OPENBLAS_CONST blasint incx, OPENBLAS_CONST double *y, OPENBLAS_CONST blasint incy);
//矩阵与向量的乘法 y := alpha*A*x + beta*y
void cblas_sgemv(OPENBLAS_CONST enum CBLAS_ORDER order, OPENBLAS_CONST enum CBLAS_TRANSPOSE trans, OPENBLAS_CONST blasint m, OPENBLAS_CONST blasint n,
这里只是其中几个比较常用的接口,OpenBlas还有很多实用接口,有兴趣的同学可以下载源码进行研究使用。
作者:费码程序猿
欢迎技术交流:QQ:255895056
转载请注明出处