Лучшая производительность для ядра при оптимизации колонии муравьев
Я пытаюсь улучшить производительность своей задачи по оптимизации колонии муравьев. Для этого я использую openCL для параллельного запуска части обновления феромонов. Я только начал изучать OpenCL, и это код ядра, который я разработал. Хотя он работает быстрее, чем последовательная версия, я все же думаю, что смогу добиться большей производительности с ним, но я не нахожу других вещей, которые я могу сделать. Есть ли способ улучшить этот код еще больше?
PS: я тестировал этот код только на процессоре, поскольку на компьютере, на котором я работаю, нет графического процессора.
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
int calculateLengthOfTrail(__global int*, const int, __global int*, const int );
int edgeInTrail(const int ,const int , __global int* , const int , const int );
int indexOfCity(__global int*, const int, const int, const int);
__kernel void updatePheromones(
__global double* pheromones,
__global int* ants,
__global int* distances,
__local double* pheromones_old,
const int numCities,
const int numAnts,
const double pheromoneDecreaseFactor,
const double pheromoneIncreaseFactor
)
{
int i = get_global_id(0);
int k, j;
if(i<numCities)
{
for(j = i +1; j<numCities; j++)
{
for (k = 0; k < numAnts; k++)
{
double size = calculateLengthOfTrail(ants,k, distances, numCities);
double decrease = (1.0 - pheromoneDecreaseFactor) * pheromones_old[i+numCities*j];
double increase = 0.0;
int edge = edgeInTrail(i, j, ants, k, numCities);
if (edge== 1)
increase = (pheromoneIncreaseFactor / size);
pheromones[i+numCities*j] = decrease + increase;
if (pheromones[i+numCities*j] < 0.0001)
pheromones[i +numCities*j] = 0.0001;
else if (pheromones[i + numCities*j] > 100000.0)
pheromones[i+numCities*j] = 100000.0;
pheromones[j+numCities*i] = pheromones[i+numCities*j];
}
}
}
}
int edgeInTrail(const int cityX, const int cityY, __global int* ants, const int row, const int numCities)
{
int lastIndex = numCities - 1;
int indexCity = indexOfCity(ants, row, cityX, numCities);
if (indexCity == 0 && ants[1+numCities*row] == cityY)
return 1;
else if (indexCity == 0 && ants[lastIndex+numCities*row] == cityY)
return 1;
else if (indexCity == 0)
return 0;
else if (indexCity == lastIndex && ants[(lastIndex-1)+numCities*row] == cityY)
return 1;
else if (indexCity == lastIndex && ants[row*numCities] == cityY)
return 1;
else if (indexCity == lastIndex)
return 0;
else if (ants[(indexCity-1)+numCities*row] == cityY)
return 1;
else if (ants[(indexCity+1)+numCities*row] == cityY)
return 1;
else
return 0;
}
int calculateLengthOfTrail(__global int* ants, const int row, __global int* distances, const int numCities)
{
int sumDistance = 0;
int i;
for(i =0; i<numCities-1; i++)
sumDistance += distances[ants[i+numCities*row]+numCities*ants[(i+1)+numCities*row]];
return sumDistance;
}
int indexOfCity(__global int* ants, int row, int city, int numCities)
{
int i;
for(i =0; i<numCities; i++)
{
if(ants[i+numCities*row] == city)
return i;
}
return -1;
}