Мне нужно выполнить несколько целочисленных делений на горячем пути моего кода. С помощью профилирования и подсчета циклов я уже определил, что целочисленные деления обходятся мне дорого. Я надеюсь, что я могу что-то сделать, чтобы сократить дивизии до чего-то более дешевого.
На этом пути я делю на 2 ^ n + 1, где n - переменное. По сути, я хочу оптимизировать эту функцию, чтобы удалить оператор деления:
unsigned long compute(unsigned long a, unsigned int n)
{
return a / ((1 << n) + 1);
}
Если бы я делил на 2 ^ n, я бы просто заменил div сдвигом вправо на n. Если бы я делил на константу, я бы позволил силе компилятора уменьшить это конкретное деление, вероятно, превратив его в умножение и некоторые сдвиги.
Есть ли аналогичная оптимизация, которая применяется к 2 ^ n + 1?
Изменить: здесь может быть произвольное 64-битное целое число. n принимает только несколько значений от 10 до, скажем, 25. Я, конечно, могу предварительно вычислить некоторые значения для каждого n, но не для a.
a
- 64-битное целое число, вы должны объявить его как таковое.unsigned long
гарантированно будет иметь только 32 бита. Используйте для этогоuint64_t
илиuint_least64_t
. Для1 << n
, если вашn
может когда-либо перейти на31
, у вас может быть неопределенное поведение. Вместо этого используйтеUINT64_C(1) << n
. - person Jens Gustedt   schedule 26.10.2010