Вариант деления через умножение (a / b == a * (1/b)) + две итерации Ньютона-Рафсона :). (источник не помню, откуда-то с гитхаба).
Проверил прирост скорости очень грубо - 1.67 раза на делении в цикле (накладные на цикл не учтены, надо будет развернуть цикл, перепроверить, думаю, что там >2 раз gain).
Работает и в Си м в Си++.
Использовать так: float a = DIV(b, c)
__attribute__((always_inline)) inline float recipsf2(float input) {
float result, temp;
asm(
"recip0.s %0, %2\n"
"const.s %1, 1\n"
"msub.s %1, %2, %0\n"
"madd.s %0, %0, %1\n"
"const.s %1, 1\n"
"msub.s %1, %2, %0\n"
"maddn.s %0, %0, %1\n"
:"=&f"(result),"=&f"(temp):"f"(input)
);
return result;
}
#define DIV(a, b) (a)*recipsf2(b)
Прирост скорости так же обеспечивается тем, что параметры передаются сразу в регистрах FPU: по какой-то причине компилятор GCC для Xtensa передает float в регистрах общего назначения, а потом перепаковывает в float регистры. Такой подход снижает возможности по оптимизации самим компилятором, поэтому - кладем переменные сразу в F регистры, высвобождая 3 обычных регистра.
Точность будет ниже, но приемлемо.