Підсумок:
Я шукаю найшвидший спосіб розрахунку
(int) x / (int) y
не отримуючи винятку для y==0
. Натомість я просто хочу довільний результат.
Фон:
При кодуванні алгоритмів обробки зображень мені часто потрібно ділити на (накопичене) значення альфа. Найпростіший варіант - звичайний код C з цілою арифметикою. Моя проблема полягає в тому, що я зазвичай отримую поділ на нульову помилку для пікселів результатів alpha==0
. Однак це саме пікселі, де результат зовсім не має значення: мені не важливо значення кольорів пікселів alpha==0
.
Деталі:
Я шукаю щось на кшталт:
result = (y==0)? 0 : x/y;
або
result = x / MAX( y, 1 );
x і y - натуральні числа. Код виконується величезна кількість разів у вкладеному циклі, тому я шукаю спосіб позбутися від умовного розгалуження.
Коли y не перевищує діапазон байтів, я задоволений рішенням
unsigned char kill_zero_table[256] = { 1, 1, 2, 3, 4, 5, 6, 7, [...] 255 };
[...]
result = x / kill_zero_table[y];
Але це, очевидно, не дуже добре для великих діапазонів.
Я думаю, що остаточне питання полягає в тому, що найшвидший біт-подвійний злом зміни 0 на будь-яке інше ціле значення, залишаючи без змін усі інші значення?
Роз'яснення
Я не на 100% впевнений, що розгалуження занадто дороге. Однак використовуються різні компілятори, тому я віддаю перевагу бенчмаркінгу з невеликими оптимізаціями (що справді сумнівно).
Напевно, компілятори чудові, коли справа доходить до подвійного скручування, але я не можу виразити результат "не байдуже" на C, тому компілятор ніколи не зможе використовувати весь спектр оптимізацій.
Код повинен бути повністю сумісним C, основними платформами є Linux 64 біт з gcc & clang та MacOS.
y += !y
? Для обчислення цього не потрібно жодної гілки. Ви можете порівняти x / (y + !y)
проти, x / max(y, 1)
а може, і y ? (x/y) : 0
. Я думаю, що в жодному з них не буде відділення, принаймні з увімкненими оптимізаціями.
0
секції є величезними та суміжними. Тут є місце для обертання мікро-оптимізаціями, а операції за пікселем - саме це місце.