【问题标题】:Fastest computation of sum x^5 + x^4 + x^3...+x^0 (Bitwise possible ?) with x=16x=16 的总和 x^5 + x^4 + x^3...+x^0(可能按位计算?)的最快计算
【发布时间】:2014-01-04 01:55:32
【问题描述】:

对于利用缓存行预取的树布局(reading _next_ cacheline 很便宜),我需要以非常快速的方式解决地址计算。我能够将问题归结为:

newIndex = nowIndex + 1 + (localChildIndex*X)

x 例如:X = 45 + 44 + 43 + 42 +40.

注意:4 是分支因子。实际上它将是 16,所以是 2 的幂。这应该对使用按位的东西有用吗?

如果它需要一个循环来计算 X (performancewise) 和除法/乘法之类的东西,那就太糟糕了。这是一个有趣的问题,我无法想出一些好的计算方法。

由于它是树遍历的一部分,因此可以使用 2 种模式:绝对计算,独立于先前的计算和增量计算,从将高 X 保存在变量中开始,然后在每个更深层次对其进行一些最小的操作树。

我希望我能够弄清楚数学应该做什么。不确定是否有办法快速且无循环地做到这一点 - 但也许有人可以提出一个非常聪明的解决方案。我要感谢大家的帮助 - StackOverflow 过去一直是我的好老师,我希望随着我知识的增长,将来能够回馈更多。

【问题讨论】:

  • 澄清一下:^ 是幂还是异或?
  • 身份:X^n + X^(n-1) + ... + X^1 + X^0 = {X^(n + 1) - 1} / {X - 1}
  • 也是x 变量吗?否则这将是微不足道的。
  • @Nabla - 好点。如果x是固定的,只需计算一次并存储即可。
  • 它的力量。对不起,应该澄清一下。是的,x 是固定的,因为它取决于分支因子(通常为 16)。我也在考虑一个查找表。不过不确定。

标签: c math optimization assembly hpc


【解决方案1】:

我将以越来越复杂和普遍性的方式回答这个问题。

  • 如果 x 固定为 16,则只需使用常量值 1118481。万岁! (命名它,使用神奇的数字是不好的做法)

  • 如果您在编译时知道一些情况,请使用一些常量甚至定义,例如:

    #define X_2 63
    #define X_4 1365
    #define X_8 37449
    #define X_16 1118481
    ...
    
  • 如果您在执行时有多个已知情况,请初始化并使用以指数为索引的查找表。

    int _X[MAX_EXPONENT]; // note: give it a more meaningful name :)
    

    初始化它,然后在执行时使用 2^exp 的已知指数进行访问。

    newIndex = nowIndex + 1 + (localChildIndex*_X[exp]);
    
  • 这些值是如何预先计算的,或者如何在运行中有效地计算它们: 和X = x^n + x^(n - 1) + ... + x^1 + x^0 是一个geometric serie,它的有限和是:

    X = x^n + x^(n - 1) + ... + x^1 + x^0 = (1-x^(n + 1))/(1-x)
    
  • 关于按位运算,正如 Oli Charlesworth 所说,如果 x 是 2 的幂(二进制 0..010..0)x^n 也是 2 的幂,并且 不同 2 的幂等价于 OR 操作。因此我们可以这样表达:

    exp 为指数,使得 x = 2^exp。 (对于 16,exp = 4)。那么,

    X = x^5 + ... + x^1 + x^0
    X = (2^exp)^5 + ... + (2^exp)^1 + 1
    X = 2^(exp*5) + ... + 2^(exp*1) + 1
    

    现在使用按位,2^n = 1<<n

    X = 1<<(exp*5) | ... | 1<<exp | 1
    

    在 C 中:

    int X;
    int exp = 4; //for x == 16
    X = 1 << (exp*5) | 1 << (exp*4) | 1 << (exp*3) | 1 << (exp*2) | 1 << (exp*1) | 1;
    
  • 最后,我忍不住要说:如果你的表达式更复杂,你必须在 x 中计算任意多项式 a_n*x^n + ... + a_1*x^1 + a_0,而不是实现明显的循环,这是一种更快的计算多项式使用Horner's rule

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 2013-12-03
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多