c++ - OpenMP 使用映射并行化 for 循环

标签 c++ openmp stdmap icc

我正在尝试并行化扫描 std::map 的 for 循环。下面是我的玩具程序:

#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <cassert>
#include <omp.h>

#define NUM 100000

using namespace std;

int main()
{
  omp_set_num_threads(16);
  int realThreads = 0;
  string arr[] = {"0", "1", "2"};
  std::map<int, string> myMap;
  for(int i=0; i<NUM; ++i)
    myMap[i] = arr[i % 3];

  string is[NUM];

  #pragma omp parallel for
  for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); it++)
  {
    is[it->first] = it->second;
    if(omp_get_thread_num() == 0)
      realThreads = omp_get_num_threads();
  }
  printf("First for-loop with %d threads\n", realThreads);

  realThreads = 0;
  #pragma omp parallel for
  for(int i=0; i<NUM; ++i)
  {
    assert(is[i] == arr[i % 3]);
    if(omp_get_thread_num() == 0)
      realThreads = omp_get_num_threads();
  }
  printf("Second for-loop with %d threads\n", realThreads);
  return 0;
}

编译命令:

icc -fopenmp foo.cpp

上述代码块的输出是:

First for-loop with 1 threads
Second for-loop with 16 threads

为什么我无法并行化第一个 for 循环?

最佳答案

std::map 不提供随机访问迭代器,仅提供通常的双向迭代器。 OpenMP 要求并行循环中的迭代器是随机访问类型。对于其他类型的迭代器,应使用显式任务:

#pragma omp parallel
{
  #pragma omp master
  realThreads = omp_get_num_threads();

  #pragma omp single
  for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); it++)
  {
    #pragma omp task
    is[it->first] = it->second;
  }
}

请注意,在这种情况下,将为映射的每个成员创建一个单独的任务。由于任务主体的计算非常简单,因此在这种特定情况下 OpenMP 开销会相对较高。

关于c++ - OpenMP 使用映射并行化 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22926399/

相关文章:

c++11 随机 double 使用 uniform_real_distribution

c++ - 在不指定字符串长度的情况下使用 sprintf_s 使 C++ 应用程序崩溃

c++ - 如何在工作线程中重用主线程创建的 OMP 线程池?

c++ - std::map 按数据排序?

c++ - 开源中的 M2M

c++ - OpenCV:使用 C++ 添加包含 alpha 信息 'on top of each other' 的矩阵

c - 外部并行循环中的内部顺序循环 - OMP

c++ - 是否可以关闭 gcc 的自动并行化?

c++ - 在 std::map 中搜索时堆栈溢出

c++ - 如何从 map 中获取值?