gcc — нужна помощь в оптимизации скорости для функции цикла / скалярного произведения в переполнении стека

Я определил функцию в узком канале, которая отвечает за 50% времени в моей программе (поиск ближайших соседей). Он рассчитывает евклидово расстояние между двумя единичными векторами. Есть ли способ сделать это быстрее? (в настоящее время я использую GCC -march=native а также -ffast-math флаги)

template<typename T>
static inline T distance(const T* x, const T* y, int f) {
T pp = 0, qq = 0, pq = 0;
for (int z = 0; z < f; z++, x++, y++) {
pp += (*x) * (*x);
qq += (*y) * (*y);
pq += (*x) * (*y);
}
T ppqq = pp * qq;
if (ppqq > 0) return 2.0 - 2.0 * pq / sqrt(ppqq);
else return 2.0;
}

1

Решение

Этот код в высшей степени парализован, вы можете попробовать использовать OpenMP или небольшой поток, чтобы сделать вычисления в разных потоках.

template<typename T>
static inline T distance(const T[] x, const T[] y, int f) {
T pp = 0, qq = 0, pq = 0;
#pragma omp parallel for private(x,z) reduction(*:pp)
for (int z = 0; z < f; z++, x++) {
pp += (*x) * (*x);
}
}

OpenMP — это библиотека Paralelization, которая опирается на Pragmas для паралелизации кода, она действительно распространена в научных вычислениях. Вы можете легко создавать темы, указав прагму над выражением, которое вы хотите парализовать.

Самый простой формат

#pragma omp parallel for
for(int i = 0; i < 10000; i++) {
paralelized code here
}

Это позаботится о создании потоков, выполнении парализованного кода и присоединении потоков к вам с помощью простого определения #pragma.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector