У меня есть фрагмент кода, который отслеживает 4 синуса за раз.
Мой оригинальный код выполнял примерно 12000 вызовов функции sin() на каждый кадр и работал со скоростью 30 кадров в секунду.
Я попытался оптимизировать его, создав таблицы поиска. Я закончил с 16 различными таблицами поиска. Я объявил и загрузил их в отдельный заголовочный файл в верхней части моей программы. Каждая таблица объявляется так:
static const float d4_lookup[800] {...};
Теперь, с помощью этого нового метода, я действительно потерял fps?! Сейчас я использую 20 кадров в секунду вместо 30. Каждый кадр теперь должен делать только 8 вызовов sin/cos и 19200 запросов поиска против вызовов 12000 sin(). Я компилирую с использованием gcc с флагом -O3. В настоящий момент таблицы поиска включены вверху и являются частью глобальной области действия программы.
Я предполагаю, что не загружаю их в правильную память или что-то в этом роде. Как ускорить время поиска?
** РЕДАКТИРОВАТЬ 1 **
В соответствии с запросом, здесь функция, которая использует вызовы поиска, вызывается один раз для каждого кадра:
void
update_sines(void)
{
static float c1_sin, c1_cos;
static float c2_sin, c2_cos;
static float c3_sin, c3_cos;
static float c4_sin, c4_cos;
clock_gettime(CLOCK_MONOTONIC, &spec);
s = spec.tv_sec;
ms = spec.tv_nsec * 0.0000001;
etime = concatenate((long)s, ms);
c1_sin = sinf(etime * 0.00525);
c1_cos = cosf(etime * 0.00525);
c2_sin = sinf(etime * 0.007326);
c2_cos = cosf(etime * 0.007326);
c3_sin = sinf(etime * 0.0046);
c3_cos = cosf(etime * 0.0046);
c4_sin = sinf(etime * 0.007992);
c4_cos = cosf(etime * 0.007992);
int k;
for (k = 0; k < 800; ++k)
{
sine1[k] = a1_lookup[k] * ((bx1_sin_lookup[k] * c1_cos) + (c1_sin * bx1_cos_lookup[k])) + d1_lookup[k];
sine2[k] = a2_lookup[k] * ((bx2_sin_lookup[k] * c2_cos) + (c2_sin * bx2_cos_lookup[k])) + d2_lookup[k] + 50;
sine3[k] = a3_lookup[k] * ((bx3_sin_lookup[k] * c3_cos) + (c3_sin * bx3_cos_lookup[k])) + d3_lookup[k];
sine4[k] = a4_lookup[k] * ((bx4_sin_lookup[k] * c4_cos) + (c4_sin * bx4_cos_lookup[k])) + d4_lookup[k] + 50;
}
}
** ОБНОВЛЕНИЕ **
Для тех, кто читает эту тему, я отказался от этой проблемы. Я попытался использовать ядра OpenCL, структуры, инструкции SIMD, а также все приведенные здесь решения. В итоге исходный код, вычисляющий sinf() 12800 на кадр, работал быстрее, чем таблицы поиска, поскольку таблицы поиска не вписывались в кеш. Тем не менее он все еще делал только 30 кадров в секунду. Это было слишком много, чтобы идти в ногу с моими ожиданиями в 60fps. Я решил пойти в другом направлении. Спасибо всем, кто внес свой вклад в эту тему. Большинство из этих решений, вероятно, будут работать, чтобы получить половину достойных улучшений скорости, но ничего, как скорость на 200%, которая мне нужна здесь, чтобы таблицы поиска работали так, как я хотел.