【发布时间】:2013-06-14 00:02:07
【问题描述】:
我最近开始在 Ubuntu 12.04 上使用 tbb 版本 4.0+r233-1 来加速视频全景拼接器。我看到的错误有点奇怪,希望有人能阐明这个问题。
似乎发生的事情是令牌无序到达接收器节点(尽管我很难相信这实际上是 TBB 中的一个错误)。我在混合视频帧中看到 抖动(例如,当显示混合帧 N 时,正在显示混合帧 N + 3,这导致视频看起来口吃)。我知道这与并行过滤器有关,因为如果我将飞行中的数字标记设置为 1 而不是 4,则不再发生口吃。
我的管道架构如下:
Read Frames Vector from files (serial) -> Warp Frames Vector (parallel) -> Blend Frames Vector (parallel) -> Write Blended Frame to file (serial)
以下是相关的代码片段,我相信会显示问题区域:
PipelineStitcher.h
class PipelinedStitcher {
public:
PipelinedStitcher(
const std::string& projectFilename,
const std::string& outputFilename,
double scaleFactor);
...
void run();
private:
std::vector<PanoramaParameters> panoParams;
std::vector<cv::Mat> readFramesFromVideos();
std::vector<cv::Mat> warpFrames(const std::vector<cv::Mat>& frames);
cv::Mat blendFrames(std::vector<cv::Mat>& warpedFrames);
};
PipelineStitcher::run()
void PipelinedStitcher::run()
{
parallel_pipeline( 4,
make_filter< void, std::vector<Mat> > (
tbb::filter::serial,
[&](flow_control & fc)-> std::vector<Mat>
{
vector<Mat> frames = readFramesFromVideos();
if(frames.empty())
{
fc.stop();
}
return frames;
}
) &
make_filter< std::vector<Mat>, std::vector<Mat> > (
tbb::filter::parallel,
[&](std::vector<Mat> src) {
vector<Mat> dst = warpFrames(src);
return dst;
}
) &
make_filter< std::vector<Mat>, Mat > (
tbb::filter::parallel,
[&](std::vector<Mat> src) {
Mat dst = blendFrames(src);
return dst;
}
) &
make_filter<Mat, void> (
tbb::filter::serial,
[&](Mat src) {
if(!videoWriter.isOpened())
{
videoWriter.open(outputFilename, CV_FOURCC('D','I','V','X'), 30.0, src.size(), true);
}
videoWriter << src;
imshow("panoramic view", src);
waitKey(3);
}
)
);
videoWriter.release();
}
几个问题:
- 由于
warpFrames和blendFrames都访问成员变量vector<PanoramaParameters> panoParams,这个成员应该是concurrent_vector类型?这些参数在 构造函数并且从未更新。 - 可能导致混合帧到达末端过滤器的原因 用 TBB 订购?
2013 年 6 月 19 日更新:
感谢@AlexeyKukanov,我能够证明令牌肯定会按顺序到达。似乎发生的情况是,当所有 CPU 内核都处于 100% 利用率时,源过滤器或接收器过滤器都会出现缓冲问题。我有一个 4 核处理器,一旦我允许 4 个令牌在飞行中,CPU 就会完全饱和并且开始出现口吃。但是,当 1、2 或 3 个标记在飞行中时,似乎没有任何卡顿。
任何帮助将不胜感激!
【问题讨论】:
-
tbb::filter::serial已弃用。最好是明确的tbb::filter::serial_in_order。 (但两个标志的值相等。) -
TBB 的使用似乎是正确的。要确定根本原因是否在代码中的 TBB 或其他地方,我建议检查最后一个过滤器中的帧是否真的出现故障,例如通过打印在第一个过滤器中分配的订单 ID。
-
@AlexeyKukanov 好主意。我将添加一种方法来跟踪整个管道中的令牌。有没有办法访问管道的当前令牌,还是我需要用我自己的自定义包装数据结构单独跟踪它?
-
不幸的是,你必须自己做;令牌 ID 是未公开的实现细节。
-
@AlexeyKukanov 感谢您的提示!它确实帮助我至少开始隔离问题的来源。
标签: c++ multithreading parallel-processing multiprocessing tbb