今天才发现opencv中集成了gemm啊!!之前花了很多时间在OpenBlas的上,今天在看Opencv的代码发现opencv中都已经集成了gemm函数,代码是C语言写的,2.4.9版本的文件在modules/core/src/matmul.cpp中。
函数定义如下:
void cv::gemm( InputArray matA, InputArray matB, double alpha,
InputArray matC, double beta, OutputArray _matD, int flags )
函数体相当复杂,代码行数将近600行。计算的是:
代码:
#include "opencv2/core/core.hpp"
#include
#include
#include
#include
using namespace std;
using namespace cv;
#define LEN 30
float timeOpenCV[LEN];
float timeOpenBlas[LEN];
int main(){
_LARGE_INTEGER time_start, time_over;
LARGE_INTEGER f;
QueryPerformanceFrequency(&f);
double dqFreq = (double)f.QuadPart;
RNG &rng = theRNG();
double alpha = 1.f, gamma = 0;
int factor = 1;
for (int i = 0; i < LEN; i++){
factor += 10;
int m = 5 * factor, p = 10 * factor, n = 5 * factor;
Mat_<float> A(m, p, CV_32F), B(p, n, CV_32F), C = Mat::zeros(m, n, CV_32F);
rng.fill(A, RNG::NORMAL, 1, 100);//mean=1,stddev=100
rng.fill(B, RNG::NORMAL, 2, 50);
QueryPerformanceCounter(&time_start);
cv::gemm(A, B, alpha, C, gamma, C);
QueryPerformanceCounter(&time_over);
timeOpenCV[i] = (time_over.QuadPart - time_start.QuadPart) / dqFreq * 1000;//milliseconds
float *src1, *src2, *src3;
src1 = (float*)A.data;
src2 = (float*)B.data;
src3 = (float*)C.data;
QueryPerformanceCounter(&time_start);
cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, m, n, p,
(float)alpha, src1, m, src2, p, (float)gamma, src3, m);
QueryPerformanceCounter(&time_over);
timeOpenBlas[i] = (time_over.QuadPart - time_start.QuadPart) / dqFreq * 1000;//milliseconds
}
for (int i = 0; i < LEN; i++){
cout << timeOpenCV[i] << " ";
}
cout << endl;
for (int i = 0; i < LEN; i++){
cout << timeOpenBlas[i] << " ";
}
system("pause");
return 0;
}
得到的结果在MATLAB中显示如下:
这个是前10个结果的比对,可以看出:
1.OpenBlas第一次运行的时候需要很多时间,其实Opencv也有这个这个现象,第一次启动时运行时间要比第二次运行时间长点点。
2.当矩阵的维数增大时,Opencv所花的矩阵相乘时间成指数增长,而OpenBlas却保持得很好,从下面的30个数据的结果可以看出,OpenBlas所花的时间成线性增长,factor因子是成线性增长的,所以,OpenBlas中的时间复杂度是O(n),这时OpenBlas完胜OpenCV。
1.Opencv中的矩阵乘法函数gemm只适应于矩阵维数小的情况,大概加估计的话,当矩阵阶数是1000以内时,Opencv可以1000ms内完成两个矩阵相乘。
2.OpenBlas适合处理高维矩阵相乘,对于小矩阵有点像杀鸡用牛刀,当矩阵维数为1500*3000时,仍然可以在500ms以内完成两个矩阵相乘。
当然,具体时间可能跟机器有些差别,本结论是程序在Release 32bit配置下运行在AMD3.5GHz,6核64位win7系统上的结果。
另外,Opencv中不支持gemv矩阵向量相乘运算。
(转载请注明作者和出处:http://blog.csdn.net/CHIERYU 未经允许请勿用于商业用途)