【问题标题】:What is the fastest way to do integer division?进行整数除法的最快方法是什么?
【发布时间】:2012-04-17 01:23:15
【问题描述】:

使用方案我需要使用以下功能。 (所有 args 都是自然数 [0, inf) )

(define safe-div
  (lambda (num denom safe)
    (if (zero? denom)
        safe
        (div num denom))))

但是,这个函数被频繁调用并且性能不够好(速度方面)。 是否有更有效的方法来实现所需的行为(num 和 denom 的整数除法,如果 denom 为零则返回安全值)?

注意,我使用的是 Chez Scheme,但是它用于仅导入 rnrs 而不是完整 Chez 的库中。

【问题讨论】:

  • 你确定你的问题在这里? safe 是做什么的?
  • safe 是根据第一行问题在 [0, inf) 范围内的自然数,所以它什么也不做
  • 您是否编写了一些测试来检查此例程的速度,以及它与简单的整数除法有何不同?有很多事情可能会有所作为,但您肯定需要在调整之前掌握性能。

标签: performance scheme integer-division chez-scheme


【解决方案1】:

为了获得最佳性能,您需要尽可能靠近硅片。添加这样的安全检查是行不通的,除非它们被方案系统及时编译成超高效的机器代码。

我看到两个选项。一种是在 C(或程序集)中创建本机(即foreign)实现并调用它。这可能与将其打包为 lambda 不兼容,但话又说回来,lambdas 的动态特性导致符号效率,但不一定是运行时效率。 (函数指针除外,C 中不存在 lambda 表达式是有原因的,尽管它已经老了很多年。)如果你走这条路,最好退后一步,看看哪个 safe-div 的更大处理是一部分应该是原生的。如果周围的一切仍然很慢,那么加快循环中心的除法就没有什么意义了。

假设被零除预计很少见,另一种方法是只使用div,并希望它的实现速度很快。是的,这可能导致除以零,但在速度方面,有时请求宽恕比请求许可更好。换句话说,跳过除法前的检查,直接去做。如果失败,方案运行时应捕获除以零故障,您可以为其安装exception handler。这会导致异常情况下的代码变慢,而正常情况下的代码变快。希望这种权衡能够带来性能上的胜利。

最后,根据您要除以的内容,乘以倒数可能比执行实际除法更快。这需要快速的倒数计算或修改较早的计算以直接产生倒数。由于您正在处理整数,因此倒数将存储在定点中,本质上是 2^32 * 1/denom。将此乘以 num 并右移 32 位以获得商。这是成功的,因为如今更多的处理器具有单周期乘法指令,但除法在芯片上的循环中执行,这要慢得多。这可能对您的需求有点过分,但在某些时候可能会很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    相关资源
    最近更新 更多