[英]TBB parallel_pipeline tokens seem to be occasionally out of order
我最近開始在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
vector<PanoramaParameters> panoParams
類型嗎? 這些參數在構造函數中創建一次,並且從不更新。 多虧@AlexeyKukanov,我得以證明令牌確實按順序到達。 似乎發生的是,當所有CPU內核都達到100%利用率時,源過濾器或接收器過濾器都會出現緩沖問題。 我有一個4核處理器,一旦允許運行4個令牌,CPU就會完全飽和,開始卡頓。 但是,當1個,2個或3個令牌飛行時,似乎沒有任何卡頓現象。
任何幫助將不勝感激!
它是知識和建議的集合,而不是答案,但是評論太長。 我以前的評論也被復制到這里。
代碼中的TBB用法似乎正確。 為了弄清根本原因是在TBB中還是在代碼的其他地方,我建議檢查框架在最后一個過濾器中是否真的失靈,例如通過打印在第一個過濾器中分配的訂單ID。 由於TBB沒有公開內部令牌ID,因此您必須自己分配和跟蹤ID。
同樣,僅供參考,令牌的數量不必等於硬件核心的數量。 盡管此數字有效地限制了並發性,但它的存在主要是為了防止在串行過濾器中有很多令牌等待輪換時資源(例如內存)不足。
要知道的另一件事是,未指定哪個線程執行哪個過濾器;這是一個未知的過程。 實際上,任何線程都可以執行任何過濾器。 因此,例如,如果接收器過濾器在屏幕上繪制了某些內容,則需要確保可以通過任何線程完成繪制,或者將所有繪制重定向到單個線程。 據我所知,某些GUI框架可能要求所有繪圖都由單個線程完成,或者某些初始化例程在繪圖之前在每個線程中被調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.