我想创建一个映射,将整数对和整数 vector 归因于此。我的目的是以并行方式进行。为了确保我不会同时尝试 push_back 到同一个内存实体(通过多个线程),映射键对的第二个坐标负责当前线程号。然而,我遇到了问题。似乎有些值没有正确插入。我得到的不是全部 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(每个线程一个),然后在最后加入它们。
如前所述,使用互斥锁(并确保对 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());
关于c++ - 并行插入映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54190842/