Я пытаюсь написать функцию, которая вычисляет минимальную стоимость триангуляции многоугольника, используя динамическое программирование, и парализует / векторизует ее, используя OpenMP.Код, который я написал до сих пор, возвращает правильные результаты, но он слишком медленный - для многоугольников, которые сформированы более чем из 3000 точек, он даже не останавливается через 5 минут.Вот код:
#pragma omp declare simd
float dist(float x1, float y1, float x2, float y2)
{
return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
}
float triangulate(const vector<Point> &points) {
int n = points.size();
vector<vector<float>> table (n, vector<float>(n, 0));
int threads = omp_get_max_threads();
for (int gap = 0; gap < n; ++gap)
{
for (int i = 0, j = gap; j < n; ++i, ++j)
{
if (j < i+2)
table[i][j] = 0.0;
else
{
int size = j - i - 1;
Point p1 = points[i], p2 = points[j];
//Precompute distance between i and j
float ij = dist(p1.x, p1.y, p2.x, p2.y);
float minimum = MAX;
#pragma omp parallel for simd schedule(static, 64) num_threads(threads) reduction(min:minimum) if(size > 300)
for (int k = i+1; k < j; ++k)
{
Point p3 = points[k];
float perimeter = ij + dist(p1.x, p1.y, p3.x, p3.y) + dist(p2.x, p2.y, p3.x, p3.y) + table[i][k] + table[k][j];
if(perimeter < minimum)
{
minimum = perimeter;
}
}
table[i][j] = minimum;
}
}
}
return table[0][n-1];
}
Разрыв и i, j для циклов imho нельзя распараллелить, поэтому можно распараллелить только цикл for над k.Я пытался подыгрывать графику, но без улучшений.Я что-то упустил или просто эта функция не может быть быстрее в рамках этого подхода?