使用/为TBB构建分组数据结构
Constructing a grouped data structure with/for TBB
最近我一直在考虑使用TBB而不是boost.threads来加速开发。一般来说,parallel_fo在大多数情况下都能工作,但我这里的情况有点复杂。
有一个结构数组需要根据成员变量排序的计算。这是因为变量值与将在计算期间访问的数据有关,并且根据该值对结构进行分组将允许串行设计中的缓存一致性。
#include <tbb/tbb.h>
#include <iostream>
struct thing
{
float value_one;
float value_two;
unsigned int sort_id;
};
class functor
{
thing* m_array;
public:
functor(thing* _array) : m_array(_array) {;}
void operator()(const tbb::blocked_range<unsigned int>& r) const
{
for(int i = r.begin(); i != r.end(); ++i)
{
//Doing a computation with array
m_array[i].value_one = m_array[i].value_two * m_array[i].value_two;
}
}
};
int main(int argc, char const *argv[])
{
unsigned int n = 10;
thing* array = new thing[n];
// Note the ordered id groups
array[0].sort_id = 1;
array[1].sort_id = 1;
array[2].sort_id = 1;
array[3].sort_id = 2;
array[4].sort_id = 3;
array[5].sort_id = 5;
array[6].sort_id = 5;
array[7].sort_id = 9;
array[8].sort_id = 9;
array[9].sort_id = 9;
// Do something parallel with array here...
// parallel_for(tbb::blocked_range<unsigned int>(0, n, 2), functor(array));
delete[] array;
return 0;
}
上面给出了一个简化的例子,但实际上我很可能有一个约3000万至6000万个元素的数组。
我知道parallel_fo会将数组划分为分组的范围。然而,我希望每个范围都包含一个特定id的所有结构。我不介意这个范围是否包含多个id的结构,只要它们是连续的,并且包含这两个id的全部结构。
int count = 0;
thing** blocks = new thing*[7];
int* sizes = new int[7];
int current_id = 0;
for(unsigned int i = 0; i < n; ++i)
{
if(array[i].sort_id != current_id)
{
current_id = array[i].sort_id;
blocks[count] = &array[i];
sizes[count] = 1;
++count;
}
else
{
sizes[count - 1] += 1;
}
}
parallel_for(tbb::blocked_range<unsigned int>(0, count, 2), functor(blocks, sizes));
我是否应该以某种方式将数组划分为由另一个数组指向的更小的块,然后进行并行化(如上面的代码中所示),如果是这样,什么是有效的方法来实现这一点,或者给定的示例是最优的?有没有比parallel_fo(如task_group)更适合这个问题的替代方案?
我仍然不太清楚这个问题,因为您正在混合目标和可能的方法。
如果需要对数组进行排序,则有parallel_sort
如果您需要为排序数组建立索引,其中作为键给定的sort_id
映射到主数组中给定元素组所在的索引,请使用concurrent_unordered_map
存储组(如果有大量组),并使用parallel_for
进行构建。
如果组的数量小于大约数百,则可以使用std::map
或std::unordered_map
并使用parallel_reduce
来构造局部映射并将它们合并到最终状态。
最后,当您拥有正确的组数据结构时,您可以根据需要在组之间使用parallel_for
。
附言:
称为任务的分组范围,将添加到堆栈中进行计算
听起来真的很奇怪。有一个用户函数(或C++11 lambda),可以被并行调用,以处理不同的范围[begin;end)
。如果您将函子称为"task",则可以,但不要将其与tbb::task
混合使用。
- 链表,反向函数,数据结构
- 如何使用set实现无序数据结构?
- 我们可以将数据永久保存为数据结构吗?
- C++中的可变长度数组/数据结构
- 用于存储由空格分隔的字符串的 C++/C 数据结构
- 通过 NIF 从C++返回自定义数据结构
- 编译器上的策略数据结构不起作用
- 尝试构建"lock-free"数据结构C++
- 设计将引用元素移动到开头的数据结构.C++
- 在学习数据结构之前对STL有一个了解是好的吗?
- 如何解析表示树状数据结构的字符串
- 我对数据结构、双向链表有一些问题
- 是否可以跨多个源文件构建 constexpr 数据结构?
- 在C 中,如何将其作为成员变量构建数据结构
- cpp 中是否存在一种数据结构,可以轻松地提供一种基于已存在的实例构建新结构的方法
- 将由结构构建的数组传递到将数据存储到文件中的函数
- 递归类型真的是构建不连续的任意大小数据结构的唯一方法吗
- 如何从std::initializer_list构建类似std::array的数据结构
- 构建图的最佳标准数据结构是什么?
- 使用/为TBB构建分组数据结构