Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于map的OpenMP循环并行化_C++_Openmp_Stdmap_Icc - Fatal编程技术网

C++ 基于map的OpenMP循环并行化

C++ 基于map的OpenMP循环并行化,c++,openmp,stdmap,icc,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_t

我正在尝试并行化扫描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;
}
上述代码块的输出为:

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;
  }
}
#pragma omp并行
{
#pragma-omp-master
realThreads=omp_get_num_threads();
#布拉格omp单曲
对于(map::iterator it=myMap.begin();it!=myMap.end();it++)
{
#pragma-omp任务
是[它->第一]=它->第二;
}
}

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

您如何确定是否已成功并行化?我不认为
std::map
是线程安全的,也不知道如何在不将其转换为数组的情况下并发循环first@merlin2011-输出来自omp_get_num_threads()它位于for块内。@BryanChen-我从@BryanChen那里得到了这个想法,只要OP没有更改其循环中的映射(例如添加或删除条目),并且对其进行了迭代,那么它就是线程安全的。
#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;
  }
}