程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Armadillo,Eigen,OpenCV 矩陣操作比較(Compare Armadillo, Eigen and O

Armadillo,Eigen,OpenCV 矩陣操作比較(Compare Armadillo, Eigen and O

編輯:C++入門知識

有的時候寫出來的程序慢也許並不是算法有問題,而是用的庫比較慢;也可能並不是庫本身慢,而只是你的寫法不夠高效。在經歷了無數次令人蛋疼的等待後,我決定比較一下這幾個所謂的高效的線性代數庫(OpenCV雖然目標是計算機視覺,但也提供了比較豐富的代數計算能力),看看它們的性能到底怎麼樣。   有人已經做過類似的事情了,比如  OpenCV vs. Armadillo vs. Eigen on Linux revisited,這哥們比較了這幾個庫在各種矩陣運算方面的效率,總結的比較齊全。但是,在計算機視覺領域這些還不夠,比如經常使用的相似性度量(Similarity Measure)的計算。當然後很多種方法,這裡就考慮最基本的SAD(Sum of Absolute Difference)方法吧,簡單來說就是把兩個矩陣(或者向量)相減,求個絕對值,再加起來。這個計算看起來挺簡單的,不過比較的結果令我比較意外。      先把代碼貼出來吧。   [cpp]   //  PerformanceTest.h      #pragma warning(disable:4344)   #define DEIGEN_NO_DEBUG   #define DNDEBUG      #include <emmintrin.h>   #include <opencv.hpp>   #include <vector>   #include <iostream>   #include <armadillo>   #include <Eigen/Dense>   #include "Timer.h"      using namespace std;     [cpp]   //  PerformanceTest.cpp      #include "PerformanceTest.h"      int main(void)   {       Timer timer;        //  timer       double elapsedTime; //  time in millisecond       double res;         //  SAD value       int i;              //  loop variable       float bnd = 1e5;    //  loop times          //  Armadillo       arma::mat armaA(4, 1);       arma::mat armaB(4, 1);       timer.start();       for (i = 0; i < bnd; ++i)       {           res = arma::accu(arma::abs(armaA - armaB));              //res = 0;           //for (int idx = 0; idx < 4; ++idx)           //{           //  res += abs(armaA(idx, 0) - armaB(idx, 0));           //}       }       elapsedTime = timer.getElapsedTimeInMilliSec();       cout<<"arma time : "<<elapsedTime<<" ms"<<endl;          //  Eigen       Eigen::Vector4d eiA;       Eigen::Vector4d eiB;       Eigen::Vector4d eiC;       timer.start();       for (i = 0; i < bnd; ++i)       {           res = (eiA - eiB).cwiseAbs().sum();           //res = 0;           //for (int idx = 0; idx < 4; ++idx)           //{           //  res += abs(eiA(idx,0) - eiB(idx, 0));           //}       }       elapsedTime = timer.getElapsedTimeInMilliSec();       cout<<"eigen time : "<<elapsedTime<<" ms"<<endl;          //  OpenCV       cv::Mat ocvA(4, 1, CV_64F);       cv::Mat ocvB(4, 1, CV_64F);       timer.start();       for (i = 0; i < bnd; ++i)       {           res = cv::sum(cv::abs(ocvA - ocvB))[0];           //res = 0;           //for (int idx = 0; idx < 4; ++idx)           //{           //  res += abs(ocvA.at<double>(idx, 0) - ocvB.at<double>(idx, 0));           //}       }       elapsedTime = timer.getElapsedTimeInMilliSec();       cout<<"opencv time : "<<elapsedTime<<" ms"<<endl;          //  pointer operation       double *a = (double*)_mm_malloc(4 * sizeof(double), 16);       double *b = (double*)_mm_malloc(4 * sizeof(double), 16);       int len = ocvA.rows;       timer.start();       for (i = 0; i < bnd; ++i)       {           res = 0;           for (int idx = 0; idx < len; ++idx)           {               res += abs(a[idx] - b[idx]);           }           //cout<<"i = "<<i<<endl;       }       elapsedTime = timer.getElapsedTimeInMilliSec();       cout<<"array operation : "<<elapsedTime<<" ms"<<endl;          //  release resource       _mm_free(a);       _mm_free(b);       return 0;   }       其中的計時函數用到的是 Franz Kafka 提供的跨平台高精度計時類,可以從以下地址下載 High Resolution Timer。   用以上代碼在 release 下得到的結果如下:   [plain]   arma time : 0.87827 ms   eigen time : 0.13641 ms   opencv time : 179.599 ms   array operation : 0.135591 ms     可以看出 Eigen 的時間和直接用數組運算的時間是相當的,Armadillo 的時間慢了 6~7 倍左右,而 OpenCV 已經目不忍視了,不知道 OpenCV 是怎麼想的,差距有點懸殊。   下面又做了另外一組對比,把循環中的求 SAD 部分用類似於數組的方式自己計算,結果如下   [plain]   arma time : 0.145423 ms   eigen time : 0.134772 ms   opencv time : 0.134362 ms   array operation : 0.139278 ms     這下計算時間基本上是相當的了。   通過這些對比得到兩個結論:   1、雖然這些庫在矩陣相乘等操作上可能比較高效,但是對於某些低級操作可能效率並不高   2、通過模板訪問數據並不比數組效率低,性能基本相當

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved