ARM / NEON的64位/ 32位分区更快算法?

我正在编写一个代码,其中两个地方有64位乘32位定点除法,结果取32位。 这两个地方共占用了我总时间的20%以上。 所以我觉得如果我能删除64位除法,我可以很好地优化代码。 在NEON中,我们可以有一些64位指令。 任何人都可以建议通过使用更快的实现来解决瓶颈问题。

或者如果我可以用C中的32位/ 32位除法进行64位/ 32位除法,那也没关系?

如果有人有想法,你能帮帮我吗?

我过去做了很多定点运算,并且自己做了大量的研究,寻找快速的64/32位分区。 如果你谷歌搜索“ARM部门”,你会发现很多关于这个问题的好链接和讨论。

ARM架构的最佳解决方案,即使32位除法可能无法在硬件中使用,也可以在此处:

http://www.peter-teichmann.de/adiv2e.html

这个汇编代码老,你的汇编程序可能无法理解它的语法。 但是,值得将代码移植到您的工具链中。 这是我迄今为止看到的特殊案例中最快的部门代码,相信我:我对它们进行了基准测试:-)

上次我这样做(大约5年前,对于CortexA8),这段代码比编译器生成的代码快10倍。

此代码不使用NEON。 一个NEON端口会很有趣。 不确定它是否会提高性能。

编辑:

我发现汇编程序的代码移植到GAS(GNU工具链)。 此代码正在运行和测试:

Divide.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; }