Я определил функцию в узком канале, которая отвечает за 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;
}
Этот код в высшей степени парализован, вы можете попробовать использовать 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.
Других решений пока нет …