2017-04-02 3 views
2

Je me demandais s'il y avait un moyen d'accélérer la population d'une carte non ordonnée appelée (path_from_startend). La carte non ordonnée a toujours une clé unique.Population C++ de la carte non ordonnée utilisant le multithread

#pragma omp parallel for 
    for (int i=start_index;i<end_index;++i){  
     for (int j=start_index;j<end_index;++j){ 
      string key= to_string(unique_locations[i])+to_string(unique_locations[j]); 
      //dont compute path to itself 
      if (i==j){ 
      } 
      else {    
        vector <unsigned> path = pathbot.FindPath(unique_locations[i],unique_locations[j],turn_penalty); 
        path_from_startend.insert(make_pair(key,path)); 

      } 
     } 

    } 
+1

Puisque 'path_from_startend' est partagé entre threads, l'opération d'insertion doit aller dans une section critique. Ensuite, la question est, est-ce que 'pathbot.FindPath' prend beaucoup de temps? Sinon, cela ne sert à rien, car vous remplissez la carte de manière séquentielle (en raison de la section critique). –

+0

Le FindPath est un algorithme A * qui prend un peu de temps (en millisecondes). –

+0

Alors ma réponse devrait vous aider. Je l'ai mis à jour, pour correspondre à votre code. –

Répondre

0

Vous pouvez essayer si le modèle suivant vous permet de gagner en vitesse. Vous remplissez essentiellement des cartes partielles que vous fusionnez ensuite dans toute la carte. L'accélération dépend beaucoup de la durée de construction et d'insertion des éléments. Si vos éléments sont peu coûteux à construire et à insérer, votre accélération peut même être négative, car pour chaque carte partielle, elle doit parcourir toute la carte à la recherche de doublons.

#pragma omp parallel 
{ 
    std::unordered_map < std::string, std::vector <unsigned> > partial; 

    #pragma omp for 
    for (int i = start_index; i < end_index; ++i) 
    {  
    for (int j = start_index; j < end_index; ++j) 
    { 
     std::string key = std::to_string(unique_locations[i]) 
         + std::to_string(unique_locations[j]); 

     //dont compute path to itself 
     if (i != j) 
     {    
     std::vector<unsigned> path = pathbot.FindPath(unique_locations[i], 
                 unique_locations[j], 
                 turn_penalty); 
     partial.insert(std::make_pair(key,path)); 
     } 
    } 
    } 

    #pragma omp critical 
    path_from_startend.insert(partial.begin(),partial.end()); 
} 
+0

Merci pour les pointeurs, cela m'a vraiment permis de réduire mes temps. Cependant, comme l'a mentionné @Jeremy, j'ai trouvé que: 1) Utiliser une chaîne comme une clé était assez cher 2) Je pourrais changer un peu l'algorithme pour faire de O (n) une opération au lieu de O (n^2) –