gpt4 book ai didi

c++ - tbb::concurrent_queue 容器中的 std::deque 是否等效?

转载 作者:太空宇宙 更新时间:2023-11-04 11:58:10 28 4
gpt4 key购买 nike

我正在使用 std::deque at 函数来访问元素而不从队列中弹出,因为我在不同的迭代中使用相同的队列。我的解决方案基于粗粒度多线程。现在我想让它成为细粒度的多线程解决方案。为此,我正在使用 tbb::concurrent_queue。但是我需要在 tbb::concurrent_queue 中执行 std::deque at 操作的等效函数?

编辑这就是我用 std::deque (粗粒度多线程)实现的方式请记住 dq 是静态队列(即在不同的迭代中使用多次)

vertext_found = true;
std::deque<T> dq;
while ( i < dq->size())
{
EnterCriticalSection(&h);
if( i < dq.size() )
{
v = dq.at(i); // accessing element of queue without popping
i++;
vertext_found = true;
}
LeaveCriticalSection(&h);
if (vertext_found && (i < dq.size()) && v != NULL)
{
**operation on 'v'
vertext_found = false;
}
}

我想用 tbb::concurrent_queue 达到同样的结果?

最佳答案

如果您的算法具有填充队列或消耗队列的单独 channel ,请考虑使用 tbb::concurrent_vector。它有一个可用于填充 channel 的 push_back 方法,以及一个用于消耗 channel 的 at() 方法。如果线程争用消费 channel 中的弹出元素,请考虑使用 tbb::atomic 计数器为 at() 生成索引。

如果填充和消费之间没有这种清晰的分离,使用 at() 可能会产生比它解决的问题更多的问题,即使它存在,因为它会与消费者赛跑。

如果消费过程只需要并行循环 concurrent_vector,请考虑使用 tbb::parallel_for 进行循环。 tbb::concurrent_vector 有一个支持这个习惯用法的 range() 方法。

void consume( tbb::concurrent_vector<T>& vec ) {
tbb::parallel_for( vec.range(), [&]( const tbb::concurrent_vector<T>::range_type& r ) {
for( auto i=r.begin(); i!=r.end(); ++i ) {
T value = *i;
...process value...;
}
});
}

如果消费 channel 不能使用 tbb:parallel_for,请考虑使用 TBB 原子计数器来生成索引。将计数器初始化为零并使用++ 对其进行递增。这是一个例子:

tbb::atomic<size_t> head;
tbb::concurrent_vector<T> vec;

bool pop_one( T& result ) { // Try to grab next item from vec
size_t i = head++; // Fetch-and-increment must be single atomic operation
if( i<vec.size() ) {
result = vec[i];
return true;
} else {
return false; // Failed
}
}

一般来说,此解决方案的可扩展性不如使用 tbb::parallel_for,因为计数器“头”在内存系统中引入了争用点。

关于c++ - tbb::concurrent_queue 容器中的 std::deque 是否等效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15230694/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com