[英]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 for
或omp task
公開足夠的並行工作。 因此,盡管您可能具有500次迭代的循環,但是您的程序可以在一個線程和500個線程之間運行(甚至更多,但它們只是空閑)。 這與其他並行化方法(例如pthread)不同,在pthread中,您必須管理所有線程及其作用。
現在,您的示例使用了不正確的ordered
。 只有在循環主體的一小部分需要按順序執行時,有序命令才有用。 即使這樣,性能也會非常成問題。 另外,如果要在內部使用ordered
則需要聲明要ordered
的循環。 另請參見此出色答案 。
您不應該使用命令。 相反,要確保螞蟻事先知道那里的number
,編寫代碼以使他們不需要數字,或者至少對螞蟻來說數字的順序無關緊要。 在后一種情況下,可以使用omp atomic capture
。
至於訪問共享數據。 盡量避免它。 添加omp critical
是獲得正確的並行程序的第一步,但通常會導致性能問題。 測量您的並行效率,使用並行性能分析工具找出是否適合您。 然后,您可以使用原子數據訪問或精簡(每個線程都有它們自己的數據,並且僅在完成主要工作后,所有線程的數據才會合並)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.