![](/img/trans.png)
[英]TBB parallel_pipeline tokens seem to be occasionally out of order
[英]Adjusting granularity in tbb parallel_pipeline
管道任務如下:
當我獲得解壓縮的文件內存緩沖區時,序列化的塊一個接一個地移動,因此我想以相同的方式將其傳遞到下一個過濾器,或者至少通過將序列化的塊打包成一定數量的組來調整此過程,然后通過。 但是(據我了解),tbb_pipeline使我將指針傳遞給具有所有序列化塊的緩沖區,因為每個過濾器都必須獲取指針並返回指針。
據我所知,使用並發隊列來累積序列化對象的包會殺死使用tbb_pipeline的麻煩。 此外,過濾器中operator()的常量不允許擁有我自己的中間“任務池”(但是,如果每個線程都具有自己的“任務”存儲本地副本並只是從中切出正確的片段,大)
主要問題:在這種情況下,有什么方法可以“調整”粒度? (即某個過濾器獲取指向所有序列化對象的指針,並傳遞到下一過濾器對象小包裝)
重新格式化(分割等)輸入文件幾乎是不可能的。
第二個問題:當我累積處理結果時,我並不真正在乎任何順序,我只需要匯總統計信息即可。 我可以使用並行過濾器代替serial_out_of_order並在某個地方累積每個線程的處理結果,然后將它們合並嗎?
但是(據我了解),tbb_pipeline使我將指針傳遞給具有所有序列化塊的緩沖區,因為每個過濾器都必須獲取指針並返回指針。
首先,我認為最好使用更現代,類型安全的管道形式: parallel_pipeline
。 它不要求您傳遞任何特定數據的任何特定指針。 您只需指定下一階段需要哪種類型的數據就可以對其進行處理。 因此,這與第一個過濾器如何划分要由以下過濾器處理的數據有關。
主要問題 :在這種情況下,有什么方法可以“調整”粒度? (即某個過濾器獲取指向所有序列化對象的指針,並傳遞到下一過濾器對象小包裝)
您可以安全地將一種並行算法嵌入另一種並行算法中,以便在某些階段更改粒度,例如,在頂層,第一個管道通過文件列表; 第二個管道在嵌套級別讀取文件的大塊; 最后,最里面的管道將大塊分解為一些第二階段的塊。 請參見下面的嵌套示例。
第二個問題 :我可以使用並行過濾器代替serial_out_of_order並在某個地方累積每個線程的處理結果,然后將它們合並嗎?
是的,如果不修改共享數據,則始終可以使用並行過濾器。 例如,您可以使用tbb::combinable
來收集特定於線程的部分和,然后將它們組合。
但是,如果每個線程都有自己的本地存儲用於“任務”的副本,並從中正確切出片段,那就太好了
是的,他們有。 每個線程都有其自己的本地任務池。
嵌套parallel_pipelines的一般示例
parallel_pipeline( 2/*only two files at once*/,
make_filter<void,std::string>(
filter::serial,
[&](flow_control& fc)-> std::string {
if( !files.empty() ) {
std::string filename = files.front();
files.pop();
return filename;
} else {
fc.stop();
return "stop";
}
}
) &
make_filter<std::string,void>(
filter::parallel,
[](std::string s) {
// a nested pipeline
parallel_pipeline( 1024/*only two files at once*/,
make_filter<void,char>(
filter::serial,
[&s](flow_control& fc)-> char {
if( !s.empty() ) {
char c = s.back();
s.pop_back();
return c;
} else {
fc.stop();
return 0;
}
}
) &
make_filter<char,void>(
filter::parallel,
[](char c) {
putc(c, stdout);
}
)
);
}
)
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.