Подтвердить что ты не робот

Более быстрое целочисленное деление, когда знаменатель известен?

Я работаю над устройством GPU с очень высокой задержкой целочисленного деления, несколькими сотнями циклов. Я ищу оптимизацию разделов.

Все деления на знаменатель, который находится в наборе {1,3,6,10}, однако числитель - это положительное значение времени выполнения, примерно 32000 или меньше. из-за ограничений памяти, таблица поиска может не быть хорошим вариантом.

Можете ли вы подумать об альтернативах? Я думал о вычислении обратных точек с плавающей запятой и используя их для умножения числителя.

Спасибо

PS. спасибо людям. бит-сдвиг взлома - это действительно здорово. для восстановления после округления, я использую следующий сегмент C:

// q = m/n
q += (n*(j +1)-1) < m;
4b9b3361

Ответ 1

a/b=a*(1/b)
x=(1<<16)/b
a/b=(a*x)>>16

Вы можете создать таблицу поиска для знаменателей? так как вы сказали, что 15-битные числители, вы можете использовать 17 для сдвигов, если все без знака 32 бит:

a/b=a*((1<<17)/b)>>17

Чем больше сдвиг, тем меньше ошибка округления. Вы можете выполнить проверку грубой силы, чтобы увидеть, сколько раз, если таковые имеются, это действительно неправильно.

Ответ 2

Стандартными взломами встроенных систем для этого является преобразование целочисленного деления на N в умножение на фиксированную точку на 1/N.

Предполагая, что 16 бит, 0.33333 можно представить как 21845 (десятичный). Умножьте, предоставив 32-битное целочисленное произведение и сдвиньте 16 бит.

Вы почти наверняка столкнетесь с некоторой ошибкой округления (усечения). Это может быть или не быть чем-то, с чем вы можете жить.

Возможно, стоит посмотреть на свой GPU и посмотреть, можете ли вы скомпоновать более быструю процедуру разделения по целому ряду, используя ваши знания ограниченного диапазона числителя.

Ответ 3

В книге "Хакерский восторг" Генри Уоррена имеется целая глава, посвященная целочисленному делению по константам, включая методы, которые преобразуют целое число деление на операцию умножения/сдвига/добавления.

Эта страница вычисляет магические числа для операций умножения/сдвига/добавления: