簡體   English   中英

C ++中具有OpenMP的並行算法

[英]Parallelize Algorithm with OpenMP in C++

我的問題是這樣的:

我想用C ++中的蟻群優化算法解決TSP。 現在,我已經實現了一種算法,可以迭代解決該問題。

例如:我生成500只螞蟻-他們彼此之間找到了路線。 直到前一個螞蟻結束,每個螞蟻才開始。

現在,我想將整個事情並行化-我考慮過使用OpenMP。

因此,我的第一個問題是:是否可以生成大量同時工作的線程(螞蟻數量> 500)?

我已經嘗試過了。 這是我main.cpp中的代碼:

 #pragma omp parallel for       
    for (auto ant = antarmy.begin(); ant != antarmy.end(); ++ant) {
        #pragma omp ordered
        if (ant->getIterations() < ITERATIONSMAX) {
            ant->setNumber(currentAntNumber);
            currentAntNumber++;
            ant->antRoute();
        }

    }

這是我的Ant類中的“關鍵”代碼,因為每個Ant都讀取和寫入相同的Matrix(信息素矩陣):

 void Ant::antRoute()
 {
     this->route.setCity(0, this->getStartIndex());
     int nextCity = this->getNextCity(this->getStartIndex());
     this->routedistance += this->data->distanceMatrix[this->getStartIndex()][nextCity];
     int tempCity;
     int i = 2;
     this->setProbability(nextCity);
     this->setVisited(nextCity);
     this->route.setCity(1, nextCity);
     updatePheromone(this->getStartIndex(), nextCity, routedistance, 0);

     while (this->getVisitedCount() < datacitycount) {
         tempCity = nextCity;
         nextCity = this->getNextCity(nextCity);
         this->setProbability(nextCity);
         this->setVisited(nextCity);
         this->route.setCity(i, nextCity);
         this->routedistance += this->data->distanceMatrix[tempCity][nextCity];
         updatePheromone(tempCity, nextCity, routedistance, 0);
         i++;
     }

     this->routedistance += this->data->distanceMatrix[nextCity][this->getStartIndex()];
     // updatePheromone(-1, -1, -1, 1);
     ShortestDistance(this->routedistance);
     this->iterationsshortestpath++;
}

void Ant::updatePheromone(int i, int j, double distance, bool reduce)
{

     #pragma omp critical(pheromone) 

     if (reduce == 1) {
        for (int x = 0; x < datacitycount; x++) {
             for (int y = 0; y < datacitycount; y++) {
                 if (REDUCE * this->data->pheromoneMatrix[x][y] < 0)
                     this->data->pheromoneMatrix[x][y] = 0.0;
                 else
                    this->data->pheromoneMatrix[x][y] -= REDUCE * this->data->pheromoneMatrix[x][y];
             }
         }
     }
     else {

         double currentpheromone = this->data->pheromoneMatrix[i][j];
         double updatedpheromone = (1 - PHEROMONEREDUCTION)*currentpheromone + (PHEROMONEDEPOSIT / distance);

         if (updatedpheromone < 0.0) {
            this->data->pheromoneMatrix[i][j] = 0;
            this->data->pheromoneMatrix[j][i] = 0;
         }
          else {
             this->data->pheromoneMatrix[i][j] = updatedpheromone;
             this->data->pheromoneMatrix[j][i] = updatedpheromone;
         }
     }

 }

因此,出於某些原因,omp並行for循環無法在這些基於范圍的循環上運行。 所以這是我的第二個問題-你們是否對代碼有任何建議,如何獲得基於范圍的循環不滿意。

謝謝你的幫助

因此,我的第一個問題是:是否可以生成大量同時工作的線程(螞蟻數量> 500)?

在OpenMP中,您通常不必關心活動的線程數,而應確保通過工作共享結構(如omp foromp task公開足夠的並行工作。 因此,盡管您可能具有500次迭代的循環,但是您的程序可以在一個線程和500個線程之間運行(甚至更多,但它們只是空閑)。 這與其他並行化方法(例如pthread)不同,在pthread中,您必須管理所有線程及其作用。

現在,您的示例使用了不正確的ordered 只有在循環主體的一小部分需要按順序執行時,有序命令才有用。 即使這樣,性能也會非常成問題。 另外,如果要在內部使用ordered則需要聲明要ordered的循環。 另請參見此出色答案

您不應該使用命令。 相反,要確保螞蟻事先知道那里的number ,編寫代碼以使他們不需要數字,或者至少對螞蟻來說數字的順序無關緊要。 在后一種情況下,可以使用omp atomic capture

至於訪問共享數據。 盡量避免它。 添加omp critical是獲得正確的並行程序的第一步,但通常會導致性能問題。 測量您的並行效率,使用並行性能分析工具找出是否適合您。 然后,您可以使用原子數據訪問或精簡(每個線程都有它們自己的數據,並且僅在完成主要工作后,所有線程的數據才會合並)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM