我正在尝试优化QTC视频编解码器,以便在Raspberry Pi上运行,并获得不错的性能。一个重要的瓶颈是在范围解码器中完成的32位整数除法,其考虑了解码时间的18%。由于设备的ARM处理器显然缺少整数除法指令,我认为可以轻松优化它。分工必须准确。
每个调用中特定除法中的被除数和除数都是不同的,但已知除数总是小于65536.我考虑建立一个逆除数值的查找表。使用该表我可以使用乘法而不是除法。查找表的大小为256千字节。
答案 0 :(得分:5)
还可以利用Raspberry Pi包含FP单元的事实,该FP单元能够执行双精度FP分割,这比整数分割的软件仿真更快。用a = b / c
替换所有整数除法a = (double)b / (double)c
对我有用。
答案 1 :(得分:2)
如果你想使用魔术乘法+ LUT,这里有一些代码。
简单的测试器测试随机除数i。没有详尽地测试所有我的,但我已经在短期内工作了。对于我测试过的i,似乎可以处理被除数的所有32位状态(j = 0..2 ^ 32-1)。
实际上,你会预先计算i = 2..64k-1或某些范围的查找表(i = 0不会起作用,因为值/ 0是未定义的,i = 1不会起作用,因为它的魔力乘数超出了32位数的范围)。然后使用方程式使用i作为查找索引来获得魔术乘数'm'。根据需要改变&不要讨厌我的风格。 :P
#include <stdio.h>
int main() {
unsigned int i,j,k,m,c;
// compute j/i,
// compute k = 2^32/i
// instead of j/i, use m = ~(j*k)>>32
srand(time(0));
for(c=0;c<64;c++) {
// generate random divisor i's for testing, then fully test every j
i = rand()&0x7fff;
// precompute these and put into a lookup table, index on [i]
k = (((__int64)1)<<32)/i;
for(j=0;j!=-1;j++) {
// status updater so we know it's working...
if(!(j&0xfffff)) { printf("%d : %d \r", i, j); fflush(0); }
// multiply instead of divide!
m = (((__int64)j*k)+k/2)>>32;
// rare fixup
if(j - m*i >= i) m++;
if(m != j/i) {
// as long as this line doesn't print, we're ok
printf("wrong : %d %d %d got: %d should be: %d\n",
i, j, k, m, j/i);
}
}
}
}