更大的数字比小的数字难除吗?

问题描述 投票:1回答:1

我为一个,发现比较大的数字比比较小的数字更困难。

我想知道这是否与CPU相同。是否有任何硬件允许较小的数字比较大的数字被更快地划分。

例如

100 / (uint8_t) 255
100 / (char) 255
100 / (int) 255
100 / (int) 2147483647
100 / (long) 2147483647
100 / (long) 9223372036854775807

我可以想象除法过程要求更大的数字需要更多的步骤,因此需要ALU进行更多的指示。我不确定数据类型是否会对此产生任何影响?

这些数字的除法之间是否会有明显的区别?如果有机会,用较小的数字进行除法通常会更好(这是任何形式的优化)吗?

c optimization types division alu
1个回答
0
投票

取决于内部实现。考虑以下朴素的二进制长除法:

struct div_t{
  int quot;
  int rem;
};

struct div_t div(int dividend, int divisor){
    _Bool dividend_is_negative = (dividend < 0),
        divisor_is_negative = (divisor < 0),
        result_is_negative = divisor_is_negative ^ dividend_is_negative;
    unsigned quotient =0, shift, shifted;
    //if (dividend_is_negative) dividend = -dividend;
    divisor ^= -divisor_is_negative;
    divisor += divisor_is_negative;
    //if (dividend_is_negative) dividend = -dividend;
    dividend ^= -dividend_is_negative;
    dividend += dividend_is_negative;
    shifted = divisor;
    //shift divisor so its MSB is same as dividend's - minimize loops
    //if no builtin clz, then shift divisor until its >= dividend
    //such as: while (shifted<dividend) shifted<<=1;
    shift = __builtin_clz(divisor)-__builtin_clz(dividend);
    //clamp shift to 0 to avoid undefined behavior
    shift &= -(shift > 0);
    shifted<<=shift;
    do{
        unsigned tmp;
        quotient <<=1;
        tmp = (unsigned long) (shifted <= dividend);
        quotient |= tmp;
        //if (tmp) dividend -= shifted;
      dividend -= shifted & -tmp;
        shifted >>=1;
    }while (shifted >= divisor);
    //if (result_is_negative) quotient=-quotient, dividend=-dividend;
    quotient ^= -result_is_negative;
    dividend ^= -result_is_negative;
    quotient += result_is_negative;
    dividend += result_is_negative;     
    return (struct div_t){quotient, dividend};
}

显然,对于较小的数字,循环在幼稚的实现中会更快终止。

如果整个回路展开并在电路中并行化,则将占用大量芯片空间,因为每个位都依赖于较高位。对于台式机,服务器和超级计算机而言,这通常是值得的,但对于移动,嵌入式或物联网则不那么值得。

[许多可配置芯片组(risc-v,j-core等)具有快速划分和缓慢划分的选项,而有些则完全省略,让编译器执行类似我的示例的操作。

© www.soinside.com 2019 - 2024. All rights reserved.