我希望有类似的东西,tbb::task_group但在订单执行方面保证不同,例如
serial_task_group tasks;
tasks.run([]{std::cout << 1;});
tasks.run([]{std::cout << 2;});
tasks.run([]{std::cout << 3;});
tasks.wait();
// guaranteed output: 123
Run Code Online (Sandbox Code Playgroud)
有关如何使用tbb实现此目的的任何建议?
目前我有一个显式线程,只使用条件变量从队列执行.但是,使用队列的问题是我如何保证task_group中只有一个任务是活动的.
我正在探索英特尔线程构建模块中的Parallel_Scan组件,它用于关联操作,我发现Parallel_Scan比串行完成的时间多10倍.
我写的代码是:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_scan.h"
#include "tbb/tick_count.h"
using namespace std;
using namespace tbb;
template <class T>
class Body
{
T reduced_result;
T* const y;
const T* const x;
public:
Body( T y_[], const T x_[] ) : reduced_result(0), x(x_), y(y_) {}
T get_reduced_result() const {return reduced_result;}
template<typename Tag>
void operator()( const blocked_range<int>& r, Tag )
{
T temp = reduced_result;
for( int i=r.begin(); i<r.end(); ++i )
{
temp = temp+x[i];
if( …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个并发关联容器,我concurrent_unordered_map从 Thead Building Blocks 中找到了它似乎满足我的所有需求。即使我阅读了文档,我也没有找到一个关于擦除如何工作的例子。
A concurrent_unordered_map supports concurrent insertion and traversal, but not concurrent erasure. The interface has no visible locking. It may hold locks internally, but never while calling user-defined code. It has semantics similar to the C++11 std::unordered_map except as follows:
Run Code Online (Sandbox Code Playgroud)
这实际上意味着什么?只要我仅从单个线程中擦除,从该地图中擦除是否安全?如果没有,我该怎么做?
我正在使用迭代器遍历整个tbb并发哈希映射并检查每个(键,值)对.
for (MAP::pair = myHashTable.begin(); myHashTable.end(); pair++)
Run Code Online (Sandbox Code Playgroud)
如何并行化这个迭代器?
我从英特尔的 TBB 网站下载了英特尔 TBB 的预构建标头和库。我更新了 ldconfig 以将 tbb 共享库添加到 /usr/lib。然而,在使用 -tbb 编译时,使用 g++ ld 的代码返回 -1,因为它无法找到 libtbb
libtbb.so.2 存在于 /usr/lib/ 中
这是我完整的 g++ 输出
g++ hellotbb.cpp -o htbb -I$HOME/libs/tbb43/include -v -ltbb
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic …Run Code Online (Sandbox Code Playgroud) 我需要在 tbb::flow::graph(英特尔 TBB 库)中的节点之间发送一些“重”类型,即其中包含动态数组的结构。如果我尝试在一个节点中创建此类结构的实例并将其上的指针发送到另一个节点,则会出现访问冲突(这是意料之中的,因为我尝试使用来自另一个线程的数据)。
因此,传递此类参数的唯一方法是使用适当的复制构造函数按值传递它们,不是吗?但是那样我们会浪费很多时间来复制......
更新:??????建议使用 std::unique_ptr 通过节点传递此类类型。但恐怕我不明白如何实现它。例如,如何将 std::unique_ptr 与 source_node 一起使用?
更新 2:使用 std::unique_ptr<> 在 flow_graph.h 第 287 行中给出 C2280 '试图引用已删除的函数'。
所以问题仍然存在。
我有一个函数需要使用不同的数据参数运行两次。此功能需要很长时间才能运行,并且会执行繁重的计算工作。
我如何做到这一点,使用哪种 TBB 机制?或者甚至不是TBB,如果我可以用STL做到这一点,请给我一个例子。
更新:
例如,我有一个函数,它将图像作为参数并对其进行一些处理:
int Compute(cv::Mat I)
{
/* computations */
return 0;
}
void callf(cv::Mat I1, cv::Mat I2)
{
// make call of this functions parallel
Compute(I1);
Compute(I2);
}
Run Code Online (Sandbox Code Playgroud) 我构建了一个tbb::flow::graph由几个function_node对象组成的对象。在执行期间,我将多条消息传递到图中(从 ~10 到 ~100000)。有时其中一个节点会抛出异常。如果是这种情况,整个图的执行将被取消,这意味着所有消息都将被丢弃。但是,我的消息是相互独立的,我不希望它们的执行被停止。
我可以直接在节点内部捕获异常,但是当发生这种情况时,对消息的进一步处理将没有意义。
所以我的问题是:如何从图中取消或删除单个消息而不取消图中已经存在的其他消息的执行?
我有一个依赖OpenCV和TBB的VS(C++)项目,所以我为每个库创建了属性表并将它们包含在项目中.一切正常,代码编译.
昨天,我已经开始使用vcpkg包管理器了.我通过vcpkg安装了OpenCV和TBB,一切似乎都有效.我创建了一个空项目,包括两者的标题,并测试新编译的库是否有效.在验证之后,我回到了我的主项目并删除了属性表,所以我可以使用vcpkg中的库.自上次成功编译以来,我没有以任何方式更改代码.
但是当我现在尝试编译代码时,我得到了两次这个错误(在main.cpp和子模块中)
tbb\critical_section.h(53):错误C3861:'InitializeCriticalSectionEx':未找到标识符
有谁知道这里发生了什么或为什么会发生这个错误?
我自己发现了这个错误.我正在添加poco-libraries标签,因为它实际上是TBB和Poco之间的冲突.
我正在编写一个使用 `tbb::parallel_pipeline' 处理视频流的应用程序。我的第一个过滤器包含两个重要的操作,一个必须在另一个之后立即发生。
我的测试表明,当我设置max_number_of_live_tokens为 6(我拥有的过滤器数量)时,两次操作之间的延迟在 3 到 20 毫秒之间,但在设置max_number_of_live_tokens为 1时始终为 3 到 4 毫秒。第一种情况下的抖动对于我的应用程序来说是不可接受的,但我需要允许多个令牌同时运行以利用并行性。
这是我的管道设置:
tbb::parallel_pipeline(6, //max_number_of_live_tokens
// 1st Filter
tbb::make_filter< void, shared_ptr<PipelinePacket_t> >(tbb::filter::serial_in_order,
[&](tbb::flow_control& fc)->shared_ptr<PipelinePacket_t>
{
shared_ptr<PipelinePacket_t> pPacket = grabFrame();
return pPacket;
}
)
&
... // 5 other filters that process the image - all 'serial_in_order'
);
Run Code Online (Sandbox Code Playgroud)
这是我的grabFrame()功能:
shared_ptr<VisionPipeline::PipelinePacket_t> VisionPipeline::grabFrame() {
shared_ptr<PipelinePacket_t> pPacket(new PipelinePacket_t);
m_cap >> pPacket->frame; // Operation A (use opencv api to capture frame)
pPacket->motion.gyroDeg = m_imu.getGyroZDeg(); // Operation B …Run Code Online (Sandbox Code Playgroud)