2015-05-19 14 views
0

巨大差異我具有3個輸入寫的函數(掩蔽):發送oclMat到函數創建在運行時

  1. inputOCL - 一個oclMat
  2. comparisonValue - 雙值
  3. 方法 - 一個int變量決定比較方法

對於我的示例,我選擇了method = 1,它代表CMP_GT,測試inputOCL> comparisonValue是否明智。

該函數的目的是將inputOCL中不符合給定copmarison的所有元素歸零。

下面是函數掩蔽:

void masking(cv::ocl::oclMat inputOCL, double comparisonValue, int method){ 
// NOTE: method can be set to 1-->5 corresponding to (==, >, >=, <, <=, !=) 

cv::ocl::oclMat valueOCL(inputOCL.size(), inputOCL.type()); 
valueOCL.setTo(cv::Scalar(comparisonValue)); 
cv::ocl::oclMat logicalOCL; 
cv::ocl::compare(inputOCL, valueOCL, logicalOCL, method); 
logicalOCL.convertTo(logicalOCL, inputOCL.type()); 
cv::ocl::multiply(logicalOCL, inputOCL, inputOCL); 
cv::ocl::multiply(1/255.0, inputOCL, inputOCL); } 

當定時我發現在運行時運行該函數,或者直接運行的計算運行下面的代碼時之間的非常大的差異的函數:

int main(int argc, char** argv){ 

double value1 = 1.23456789; 
double value2 = 1.23456789; 

// initialize matrix 
cv::Mat I(5000, 5000, CV_64F, cv::Scalar(value1)); 
// copy input to GPU 
cv::ocl::oclMat inputOCL(I); 
int method = 1; 
static double start_TIMER; 

// computation done in function 
start_TIMER = cv::getTickCount(); 
masking(inputOCL, value2, method); 
std::cout << "\nFunction runtime = " << ((double)(cv::getTickCount() - start_TIMER))/cv::getTickFrequency() << " Seconds\n"; 

// direct computation 
start_TIMER = cv::getTickCount(); 
cv::ocl::oclMat valueOCL(inputOCL.size(), inputOCL.type()); 
valueOCL.setTo(cv::Scalar(value2)); 
cv::ocl::oclMat logicalOCL; 
cv::ocl::compare(inputOCL, valueOCL, logicalOCL, method); 
logicalOCL.convertTo(logicalOCL, inputOCL.type()); 
cv::ocl::multiply(logicalOCL, inputOCL, inputOCL); 
cv::ocl::multiply(1/255.0, inputOCL, inputOCL); 
std::cout << "\nDirect runtime = " << ((double)(cv::getTickCount() - start_TIMER))/cv::getTickFrequency() << " Seconds\n"; 
} 

運行時可以在此屏幕截圖中看到:

enter image description here

運行時間爲什麼會有這麼大的差異?

+0

只是出於興趣,你可以張貼結果從兩個couts – GPPK

+0

什麼是你測量的運行時間的範圍? – Micka

+0

我已將截圖添加到原始帖子。 –

回答

0

我想感謝asarsakov(提醒我注意破壞oclMats的問題)和DarkZeros(注意我忘記破壞函數中的第二個臨時oclMat)。

但是,這並不能反映整個解決方案。似乎我能夠實現相同的'直接'和'功能'結果的唯一方法是使用cv :: ocl :: oclMat &而不是cv :: ocl :: oclMat發送oclMats。

請參閱以下代碼(整個代碼,函數和全部),以獲得相同結果的最終解決方案。通過在主開始處更改布爾變量,我們控制計算(直接或通過函數)以及控制計時器內oclMat的釋放。

#include "opencv2/ocl/ocl.hpp" 
#include <conio.h> 

void masking(cv::ocl::oclMat &inputOCL, cv::ocl::oclMat &valueOCL, cv::ocl::oclMat &logicalOCL, double comparisonValue, int method){ 
// NOTE: the method input is 1-->5 corresponding to (==, >, >=, <, <=, !=) 
valueOCL.setTo(cv::Scalar(comparisonValue)); 
cv::ocl::compare(inputOCL, valueOCL, logicalOCL, method); 
logicalOCL.convertTo(logicalOCL, inputOCL.type()); 
cv::ocl::multiply(logicalOCL, inputOCL, inputOCL); 
cv::ocl::multiply(1/255.0, inputOCL, inputOCL); 
} 

int main(int argc, char** argv){ 

bool direct = 1; // 1 for direct, 0 for function 
bool release = 1; // 1 with releasing temporary oclMat, 0 without releasing them 

// initialize data 
int method = 1; 
static double start_TIMER; 
double value1 = 1.23456789; 
double value2 = 1.23456789; 
cv::Mat I(5000, 5000, CV_64F, cv::Scalar(value1)); 

if (direct){ 
    // direct computation 
    cv::ocl::oclMat inputOCL1(I); 
    cv::ocl::oclMat valueOCL1(inputOCL1.size(), inputOCL1.type()); 
    cv::ocl::oclMat logicalOCL1; 
    start_TIMER = cv::getTickCount(); 
    valueOCL1.setTo(cv::Scalar(value2)); 
    cv::ocl::compare(inputOCL1, valueOCL1, logicalOCL1, method); 
    logicalOCL1.convertTo(logicalOCL1, inputOCL1.type()); 
    cv::ocl::multiply(logicalOCL1, inputOCL1, inputOCL1); 
    cv::ocl::multiply(1/255.0, inputOCL1, inputOCL1);  
    if (release){ valueOCL1.release(); logicalOCL1.release(); } 
    std::cout << "\nDirect runtime = " << ((double)(cv::getTickCount() - start_TIMER))/cv::getTickFrequency() << " Seconds\n"; 
} 

if (!direct){ 
    // computation done in function 
    cv::ocl::oclMat inputOCL2(I); 
    cv::ocl::oclMat valueOCL2(inputOCL2.size(), inputOCL2.type()); 
    cv::ocl::oclMat logicalOCL2; 
    start_TIMER = cv::getTickCount(); 
    masking(inputOCL2, valueOCL2, logicalOCL2, value2, method);  
    if (release){ valueOCL2.release(); logicalOCL2.release(); } 
    std::cout << "\nFunction runtime = " << ((double)(cv::getTickCount() - start_TIMER))/cv::getTickFrequency() << " Seconds\n";  
} 

printf("\nPress any key to exit..."); 
_getch(); 
return 0; 
} 
+0

也許'cv :: ocl :: multiply'和'cv :: ocl :: compare'內部的內核也需要破壞。通常這些操作都很快,所以我不能給出解釋爲什麼要採取只要cv :: ocl。我可以確認的是,區別在於對象的破壞,如果將所有「直接」計算都包含在「{}」中,並且在封裝後執行std :: cout,那麼時間應該是相同的,因爲所有的對象都將被銷燬。 – DarkZeros