因此,我得到了一个 C++ 程序,我必须使用 TBB 对其进行并行化(使其更快)。当我查看代码时,我认为使用管道是有意义的。问题是我没有什么经验,而且我在网上找到的任何东西都让我更加困惑。这是代码的主要部分:
uint64_t cbRaw=uint64_t(w)*h*bits/8;
std::vector<uint64_t> raw(cbRaw/8);
std::vector<uint32_t> pixels(w*h);
while(1){
if(!read_blob(STDIN_FILENO, cbRaw, &raw[0]))
break; // No more images
unpack_blob(w, h, bits, &raw[0], &pixels[0]);
process(levels, w, h, bits, pixels);
//invert(levels, w, h, bits, pixels);
pack_blob(w, h, bits, &pixels[0], &raw[0]);
write_blob(STDOUT_FILENO, cbRaw, &raw[0]);
}
它实际上是读取视频文件、解压缩、应用转换、打包然后将其写入输出。这看起来很简单,所以如果您有任何可能有用的想法或资源,请分享。
提前致谢,
D.基督。
最佳答案
事实上,您可以使用 tbb::parallel_pipeline
并行处理多个视频“blob”。
基本方案是一个 3 级管道:一个输入过滤器读取一个 blob,一个中间过滤器对其进行处理,最后一个将处理后的 blob 写入文件。输入和输出过滤器应该是serial_in_order
,中间的过滤器可以是parallel
。解包和打包似乎可以在中间阶段完成(我会从中间阶段开始,以尽量减少串行阶段的工作量)或在输入和输出阶段(但这可能会更慢)。
您还需要确保数据存储(在您的情况下为 raw
和 pixels
)不会在并发处理的 blob 之间共享。也许最简单的方法是拥有一个通过管道传递的 per-blob 存储。与串行程序不同,需要在流水线阶段之间传递的存储将不可能使用自动变量;因此,您需要在输入过滤器中使用 new
分配您的存储空间,通过管道通过引用(或通过指针)传递它,然后在所有处理后 delete
在输出过滤器中完成。这对于 raw
存储来说肯定是必要的。但是,对于 pixels
,如果所有需要它的操作(即解包、处理和打包结果)都在中间过滤器的主体内完成,您可以继续使用自动变量。当然,变量的声明也应该移到那里。
让我对您的串行代码进行修改,使其更适合应用 parallel_pipeline。请注意,我将 raw
更改为动态分配的数组,而不是 std::vector
;您显示的代码似乎并没有将其用作 vector 。请注意,这只是一个草图,可能无法按原样工作。
uint64_t cbRaw=uint64_t(w)*h*bits/8;
uint64_t * raw; // now a pointer to a dynamically allocated array
while(1){
{ // The input stage
raw = new uint64_t[cbRaw/8];
if(!read_blob(STDIN_FILENO, cbRaw, raw)) {
delete[] raw;
break; // No more images
}
}
{ // The second stage
std::vector<uint32_t> pixels(w*h);
unpack_blob(w, h, bits, raw, &pixels[0]);
process(levels, w, h, bits, pixels);
//invert(levels, w, h, bits, pixels);
pack_blob(w, h, bits, &pixels[0], raw);
}
{ // The output stage
write_blob(STDOUT_FILENO, cbRaw, raw);
delete[] raw;
}
}
有a tutorial在 TBB 文档中的管道上。尝试将您的代码与那里的示例匹配;这应该很容易做到。您也可以通过 the TBB forum 寻求帮助.
关于c++ - 使用 tbb 并行化视频转换程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22133390/