OpenMP / __ gnu_parallel für eine ungeordnete Karte

Irgendwann in meinem Code muss ich Operationen für alle Elemente in einer ungeordneten Map ausführen. Um diesen Prozess zu beschleunigen, möchte ich openMP verwenden, aber der naive Ansatz funktioniert nicht:

std::unordered_map<size_t, double> hastTable;

#pragma omp for
for(auto it = hastTable.begin();
    it != hastTable.end();
    it ++){
//do something
}

Der Grund dafür ist, dass der Iterator einer unordered_map kein Iterator mit wahlfreiem Zugriff ist. Als Alternative habe ich die __gnu_parallel-Direktiven ausprobiert, die an for_each arbeiten. Aber der folgende Code

#include <parallel/algorithm>
#include <omp.h>

__gnu_parallel::for_each (hashTable.begin(), hashTable.end(),[](std::pair<const size_t, double> & item)
                        {
                          //do something with item.secon
                        });

compiled with (gcc 4.8.2)

 g++ -fopenmp -march=native -std=c++11

läuft nicht parallel. Das Umschalten der unordered_map mit einem Vektor und die Verwendung derselben __gnu_parallel-Direktive werden parallel ausgeführt.

Warum läuft es bei der ungeordneten Map nicht parallel? Gibt es Workarounds?

Im Folgenden gebe ich Ihnen einen einfachen Code, der mein Problem reproduziert.

#include <unordered_map>
#include <parallel/algorithm>
#include <omp.h>

int main(){

//unordered_map                                                                                                                                      
std::unordered_map<size_t, double> hashTable;
double val = 1.;
for(size_t i = 0; i<100000000; i++){
  hashTable.emplace(i, val);
  val += 1.;
}
__gnu_parallel::for_each (hashTable.begin(), hashTable.end(),[](std::pair<const size_t, double> & item)
                        {
                          item.second *= 2.;
                        });

//vector                                                                                                                                             
std::vector<double> simpleVector;
val = 1.;
for(size_t i = 0; i<100000000; i++){
  simpleVector.push_back(val);
  val += 1.;
}
__gnu_parallel::for_each (simpleVector.begin(), simpleVector.end(),[](double & item)
                        {
                          item *= 2.;
                        });

}

ch freue mich auf Ihre Antworte

Antworten auf die Frage(2)

Ihre Antwort auf die Frage