并行插入到映射
Parallel insertion to map
我想创建一个映射,将整数对归因为整数的向量。我的目的是以并行方式做到这一点。为了确保我不会尝试同时push_back到同一个内存实体(通过多个线程),map 键对的第二个坐标负责当前线程编号。但是,我遇到了问题。似乎某些值未正确插入。我得到的不是一起得到 10 个值,而是总是得到更少(有时是 9 个,有时是 8、6 个等)
map<pair<int, int>, vector<int> > test;
#pragma omp parallel num_threads(8)
{
#pragma omp for
for (int i = 0;i < 10;i++)
{
test[make_pair(i % 3, omp_get_thread_num())].push_back(i);
}
}
我也试过test.at(make_pair(i % 3, omp_get_thread_num())).push_back(i)
,也没用。但是,在这种情况下,执行因异常而中断。
我认为#pragma omp for
将for
循环分发到 (0,...,9) 的不相交子序列中,这样我的代码就不会有问题......我有点困惑。有人可以向我解释这个问题吗?
如前所述,标准库容器不是线程安全的。这种情况的适当解决方案是初始化 n-map(每个线程一个),然后在最后连接它们。
如前所述,使用互斥锁(并使对映射的访问安全)将是一个有效的解决方案,但它也会导致性能下降。因为每次访问映射时,每个线程都必须等待互斥锁解锁数据。
应该注意的是,10 的大小不足以使多线程变得值得,在这里使用多线程很可能会降低性能。
map<pair<int, int>, vector<int> > test[8];
#pragma omp parallel num_threads(8)
{
#pragma omp for
for (int i = 0;i < large_number; i++)
{
int thread_id = omp_get_thread_id();
test[thread_id][make_pair(i % 3, omp_get_thread_num())].push_back(i);
}
}
#pragma omp barrier
map<pair<int,int>, vector<int>> combined;
for (int i = 0; i < 8; ++i)
combined.insert(test[i].begin(), test[i].end());
这是因为映射不是线程安全的(向量也不是,但这部分不是线程的)。您必须添加互斥锁,使用无锁容器或先准备地图。
在这种情况下,通过创建所有条目从单个线程开始。
#pragma omp single
for (int i = 0;i < 3;++i)
{
for (int j = 0;i < 8;++j)
{
test.insert(make_pair(make_pair(i, j), vector<int>()));
}
}
然后做你的平行(添加一个障碍)。
相关文章:
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- 如何编写用于多映射插入和擦除功能的 API?
- C++,映射插入&&文件流读取导致麻烦
- 多映射插入键类型信息 std::make_pair vs std::p air 构造函数
- 将一个映射插入到同一多重映射的另一个映射中会导致 SEG 错误
- 将元素插入 c++ 映射 - 插入方法的差异
- 使用boost::关联属性映射插入boost::BIMAP..失败
- STL 无序映射 - 插入到向量中
- C++在映射插入期间保证移动
- Visual Studio C++-std::映射插入失败
- C++映射插入
- 标准::映射插入/擦除的并发问题
- 不明确的映射.插入boost
- 无序映射插入复制元素
- 无序映射插入()错误
- 自定义键出现c++映射插入错误
- c++多映射插入两个以上的值
- 使用配对类型的映射插入
- 调试映射插入
- STL映射插入复制构造函数