较小的速度,具有多个流程的OPENCV
Small speedup with multiple processes for opencv
在我分析电影文件的应用程序中(假设计算连续框架对的差异(。为此,我使用OpenCV(使用FFMPEG作为LIB/编解码器(。根据视频格式,有不同的CPU负载/用途。对于WMV3,似乎不超过1个核心。因此,让多个线程在电影的不同部分上工作是亲密接近的,由于数据是独立的(之后必须缝制零件(。代码(被圈参数剥离(非常简单:
int main(int argc, char *argv[])
{
const string source = "move.wmv";
VideoCapture capt(source);
if (!capt.isOpened())
{
cout << "Could not open file " << source << endl;
return -1;
}
unsigned short nThreads (8);
double *pDiffArray = new double [(size_t) (capt.get(CV_CAP_PROP_FRAME_COUNT)];
capt.release();
ComputeDifferences (source, pDiffArray, nThreads);
return 0;
}
int ComputeDifferences (const string& source, double *pDiffArray, const unsigned short& nThreads)
{
std::vector<std::thread *> threadVector;
for (unsigned int i=0; i< nThreads; i++)
threadVector.push_back (new std::thread (ComputePart, source, pDiffArray, nThreads, i));
for (unsigned int i=0; i< nThreads; i++)
threadVector.at (i)->join();
// Stitching
;
return 0;
};
void ComputePart (const string source, double *pDiffArray,
const unsigned int& nThreads, const unsigned int& nThreadNo)
{
VideoCapture capt(source);
if (!capt.isOpened())
{
cout << "Could not open file " << source << endl;
}
size_t startPosDiffArray;
startPosDiffArray = nThreadNo * (capt.get(CV_CAP_PROP_FRAME_COUNT) / nThreads);
size_t sizePart (capt.get(CV_CAP_PROP_FRAME_COUNT) / nThreads);
size_t startPosFrame;
startPosFrame = capt.get(CV_CAP_PROP_FRAME_COUNT) / nThreads * nThreadNo;
capt.set(CAP_PROP_POS_FRAMES, startPosFrame);
Size refS = Size((int) capt.get(CAP_PROP_FRAME_WIDTH),
(int) capt.get(CAP_PROP_FRAME_HEIGHT));
Mat frame, frameRes;
std::array<Mat, 2> frameDuo;
Scalar s;
capt >> frameDuo [0];
if (!frameDuo [0].data)
return;
for (size_t i = 1; i < sizePart; i++) {
capt >> frameDuo [i%2];
if (!frameDuo [i%2].data)
break;
absdiff (frameDuo [(i-1)%2], frameDuo [i%2], frameRes);
s = sum (frameRes);
pDiffArray [i-1+startPosDiffArray] = (s [0] + s [1] + s [2])/ (refS.height * refS.width);
}
capt.release();
}
如果我在WMV3视频中使用它,则为1280x720,abt。50,000帧,相对于单线线程(190秒(,我得到了这个加速度(在Intel I7上(。
- MT2 1.8
- MT4 2.6
- MT8 3.0
除了非常失望之外,我不明白这里发生了什么。我确实知道Amdahl的定律等,但是在这种情况下,我希望加快得多。有人对我有提示(对此做新手(吗?它不是定位(capt.set(((,因为禁用什么都不会改变任何东西。是关于ffmpeg-lib,opencv,std-lib的线程开关,工作集问题吗?
[编辑:
从评论中提示,我发现80%的时间在
中使用capt >> frameDuo [i%2];
这包括从文件中读取,解码和复制到OPENCV结构中。因此,只有文件的读数为"顺序类型"(从Amdahl的意义上(。由于HDD不会显示出大量的访问(即使在MT8时(也没有区别使用快速SSD时,我不明白为什么此顺序零件应该具有如此大的效果。8个核心如何完全工作,但只有3个核心?和:我该怎么做得更好?]
您数字的最大部分确实可以通过Amdahls Law来解释。如果我将您的结果用于两个线程,并尝试计算并行完成的分数,则将获得p = 0.88888的值。并将此值用于4/8线程,我得到
2 1.8
4 2.99
8 4.48
这些数字不能准确地重现您的测量值,但是在Amdahls Law的基础上,您的每个线程开销,并且必须考虑更多的东西才能获得逼真的数字,因此它只是第一个近似值,从这个意义上讲,协议还可以。
作为结论:您获得的数字还不错。在考虑Amdahls Law时,其平行分数的期望为〜85%。
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- 从 OpenCV 3 切换到 OpenCV 4 会导致网络摄像头以最大 5 fps 的速度录制,而不是通常的 30 f
- C++、OpenCV和Kinect:处理速度下降
- 较小的速度,具有多个流程的OPENCV
- 我可以加快OpenCV的'raspicam_node'发布速度吗?
- OpenCV Mat对象复制速度更快
- MATLAB与DFT中的FFT2在OpenCV C 速度比较中
- iOS上的OpenCV:二进制大小、加载时间、速度等
- OpenCV中的网络摄像头图像处理C++速度很慢
- 使用 opencv 2.3.1 捕获视频的速度较慢
- 为什么OpenCV(@Banana Pi,Raspbian)中的全屏窗口分辨率会减慢相机镜头的速度并使其滞后
- OpenCV减慢了摄像头的捕捉速度
- OpenCV ORB GPU的实现速度比CPU慢
- OpenCV速度问题
- OpenCV CUDA运行速度比OpenCV CPU慢
- 与CPU版本相比,OpenCV GPU对象检测速度慢,检测次数少
- OpenCV的执行速度(for loops和meanStdDev)
- OpenCV:C++API和C API在功能或速度上是否不同
- 如果我在opencv中使用UMat并关闭GPU处理,会有速度差异吗