我可以在C ++中使用并行线程填充std::set
对象并编辑布尔向量吗?
我对并行计算相对较新,我只是学习使用OpenMP,我听过有人说只要它们是只读的,就可以在线程之间建立共享数据结构。
我的问题是,我可以使用并行方法填充一些数据结构,只要订单不重要吗?或者你不是一般做这样的事情的原因不仅仅是订单不会被保留?
以下是我要做的事情:
input: std::vector<Object> u_set // vector containing universal set
int NUM_ELEMENTS = 1000;
std::set<int> my_set(); // set to be populated
std::vector<bool> my_bools(u_set.size(), false); // vector containing set membership information (true/false)
#pragma omp parallel for
for (int i = 0; i < NUM_ELEMENTS; ++i){
int next_el = get_next_element(); // next element from u_set
my_set.insert(next_el);
my_bools[next_el] = true;
}
代码基本上从通用集中选择一个元素,然后将其值添加到子集中,并在布尔向量中将其标记为子集的成员。可以并行执行此操作吗?还是被认为是不好的形式?这样的事情会更好吗?
input: std::vector<Object> u_set // vector containing universal set
int NUM_ELEMENTS = 1000;
std::set<int> my_set(); // set to be populated
std::vector<bool> my_bools(u_set.size(), false); // vector containing set membership information (true/false)
int max_threads = omp_get_max_threads();
std::vector<std::vector<int> > elements(max_threads); // vector to contain data from each thread, so not accessing the same data structure
#pragma omp parallel for
for (int i = 0; i < NUM_ELEMENTS; ++i){
int next_el = get_next_element(); // next element from u_set
int curr_thread = omp_get_thread_num();
elements[curr_thread].push_back(next_el);
}
for (auto it = elements.begin(); it != elements.end(); ++it){
for (auto jt = elements[*it].begin(); jt != elements[*it].end(); ++it){
my_set.insert(*jt);
my_bools[*jt] = true;
}
}
这为每个线程创建一个单独的向量,然后在最后组合它们。我知道它在技术上仍然访问相同的数据结构,但在我看来,在所有数据结构中将向量分开将使其更加安全,不会混淆。
这是一个更好的方法吗?或者只是访问同一个集合并添加到算法去了吗?
答案 0 :(得分:1)
当任何其他线程调用任何其他方法时,您无法调用const
容器的几乎所有非std
方法。 (begin()
和end()
以及其他一些例外情况。)
所以没有。
在其他并行库中使用的一种技术是每个线程在子容器中累积更改,子容器中的更改由工作线程以类似的方式自动合并到最终结果中。对于您使用的工具,这似乎不太合理。