我有一段代码,我试图并行运行,但是,由于某种原因它不会提高速度。
代码执行一组新找到的keyPoints和较旧找到的keyPoints之间的匹配,然后在500次迭代中执行RANSAC。
由于每对都是相互独立的,我希望做匹配和RANSAC可以提高速度。
以下是代码:
Eigen::VectorXf RigidChainTracker::GPUgetCamera(cv::Mat depthNew, cv::Mat colorNew, cv::Mat grayNew, deque<imgPair> oldImg, const Eigen::VectorXf &XiInit,
vector<cv::KeyPoint> foundPtsNew, cv::Mat descriptorNew, const float alpha){
vector<cv::KeyPoint> matchedOld[CHAINLENGTH];
vector<cv::KeyPoint> matchedNew[CHAINLENGTH];
FindFeatures::FindFeatures fFeatures[CHAINLENGTH];
for (int i = 0; i < CHAINLENGTH; ++i){
fFeatures[i] = FindFeatures::FindFeatures(METHOD, fx, fy, cx, cy);
}
double t1 = omp_get_wtime();
int i = 0;
int chainlength = CHAINLENGTH;
vector<cv::KeyPoint> keyPtsNew[CHAINLENGTH];
vector<cv::KeyPoint> keyPtsOld[CHAINLENGTH];
const float THRESHOLD = 0.02;
Eigen::Matrix3f Rrel[CHAINLENGTH];
Eigen::Vector3f trel[CHAINLENGTH];
#pragma omp parallel for private (i) shared(fFeatures,matchedNew, matchedOld, depthNew, colorNew, grayNew, oldImg,descriptorNew,foundPtsNew, keyPtsNew, keyPtsOld,Rrel,trel, chainlength, THRESHOLD)
for (i = 0; i < chainlength; ++i){
if (i < oldImg.size()){
fFeatures[i].MatchFeatures(depthNew, oldImg[i].depth, descriptorNew, oldImg[i].descriptor, foundPtsNew, oldImg[i].foundPts, keyPtsNew[i], keyPtsOld[i]);
fFeatures[i].RANSAC3D(depthNew, oldImg[i].depth, keyPtsNew[i], keyPtsOld[i], Rrel[i], trel[i],THRESHOLD);
matchedNew[i] = keyPtsNew[i];
matchedOld[i] = keyPtsOld[i];
}
}
当串行运行时,它以大约2-5赫兹的速度运行,但OpenMp略慢。我尝试了一些不同的东西,但我无法做到。尝试从同一个内存中读取时可能会有些奇怪,例如从depthNew或descriptorNew读取时。我将信息写入MatchFeatures和RANSAC3D中的keyPtsNew,keyPtsOld,matchedNew,matchedOld,Rrel和trel。从图像depthNew和descriptorNew,我只读取信息。串口代码真的可能更快吗?
我已经确认正在执行多个线程并且启用了visual studio中的openMP标志。 :)
我已经尝试过Avi Ginsburg的建议,它加快了并行部分的速度,但串行代码仍然更快。
我将不同功能的MatchFeatures和RANSAC3D定时。当串行运行时,每个任务最多需要0.05秒。
当并行运行时,每个任务需要0.1到0.15秒,相当慢。我试图弄清楚OpenCV是否存在一些我不知道的并行化。例如,在匹配过程中或其他任何内容。
/ Erik
答案 0 :(得分:2)
在你的情况下,由于线程之间共享大量变量,似乎就是这种情况。 共享变量具有同步开销,会影响性能。 我相信可以通过将OMP循环分成两部分来解决。第一个执行计算并创建一个新的结果数组。第二个循环遍历执行匹配的旧数组和新数组。
在并行编程中,由于设备延迟和频带限制,将值从内存传输到CACHE和寄存器的时间成本通常很大,将数据复制到每个线程的CACHE,计算它,可能是值得的,然后减少结果,而不是在线程和进程之间不断共享它以避免重复。这意味着内存优化程度较低的代码段实际上可以提高性能。