Как я могу оптимизировать эту функцию S-кривой?

Я работаю над гамма-функцией, которая генерирует S-кривую.
Мне нужно запустить его в среде реального времени, поэтому мне нужно максимально ускорить его.

Код выглядит следующим образом:

float Gamma = 2.0f; //Input Variable

float GammaMult = pow(0.5f, 1.0f-Gamma);
if(Input<1.0f && Input>0.0f)
{
if(Input<0.5f)
{
Output = pow(Input,Gamma)*GammaMult;
}
else
{
Output  = 1.0f-pow(1.0f-Input,Gamma)*GammaMult;
}
}
else
{
Output  = Input;
}

Есть ли способ, которым я могу оптимизировать этот код?

3

Решение

Вы можете избежать трубопроводные киоски устраняя разветвление на Input<1.0f && Input>0.0f если набор команд поддерживает арифметика насыщенности или используйте макс / мин встроенные, например, x86 MAXSS

Вы также должны устранить другие ответвления путем округления насыщенного Input, Полный алгоритм:

float GammaMult = pow(0.5f, 1.0f-Gamma);
Input = saturate(Input); // saturate via assembly or intrinsics
// Input is now in [0, 1]
Rounded = round(Input); // round via assembly or intrinsics
Coeff = 1 - 2 * Rounded
Output = Rounded + Coeff * pow(Rounded + Coeff * Input,Gamma)*GammaMult;

Округление должно быть сделано также через asm / intrinsics.

Если вы используете эту функцию, например, последовательные значения массива, вы должны рассмотреть его векторизацию, если целевая архитектура поддерживает SIMD.

3

Другие решения

Ваш код кажется в порядке. Узким местом, если оно существует, является pow функция. Единственное решение состоит в том, чтобы пойти немного глубже в детали низкого уровня и попытаться реализовать свой собственный pow функция. Например, если вам достаточно 2-х чисел с плавающей запятой, вы можете найти некоторые основанные на приближении алгоритмы, которые работают быстрее.

Видеть это: Наиболее эффективный способ реализации функции pow () в плавающей точке

0

По вопросам рекламы [email protected]