我过去做过很多定点运算,我自己也做过很多研究来寻找快速的 64/32 位除法。如果你在谷歌上搜索“ARM 部门”,你会发现 吨 很多关于这个问题的链接和讨论。
ARM 架构的最佳解决方案,即使是 32 位除法也可能在硬件中不可用:
http://www.peter-teichmann.de/adiv2e.html
这个汇编代码非常老了,你的汇编器可能不理解它的语法。然而,值得将代码移植到您的工具链中。这是迄今为止我见过的针对您的特殊情况的最快除法代码,相信我:我已经对它们进行了基准测试:-)
我上次这样做时(大约 5 年前,对于 CortexA8),这段代码比编译器生成的代码快了大约 10 倍。
此代码不使用 NEON。 NEON 端口会很有趣。但不确定它是否会大大提高性能。
编辑:
我发现将汇编程序移植到 GAS(GNU 工具链)的代码。此代码正在运行并经过测试:
除法.S
.section ".text"
.global udiv64
udiv64:
adds r0,r0,r0
adc r1,r1,r1
.rept 31
cmp r1,r2
subcs r1,r1,r2
adcs r0,r0,r0
adc r1,r1,r1
.endr
cmp r1,r2
subcs r1,r1,r2
adcs r0,r0,r0
bx lr
C 代码:
extern "C" uint32_t udiv64 (uint32_t a, uint32_t b, uint32_t c);
int32_t fixdiv24 (int32_t a, int32_t b)
/* calculate (a<<24)/b with 64 bit immediate result */
{
int q;
int sign = (a^b) < 0; /* different signs */
uint32_t l,h;
a = a<0 ? -a:a;
b = b<0 ? -b:b;
l = (a << 24);
h = (a >> 8);
q = udiv64 (l,h,b);
if (sign) q = -q;
return q;
}