【问题标题】:shift bits vs multiply in PHPPHP中的移位与乘法
【发布时间】:2012-01-05 07:08:18
【问题描述】:

我有以下代码:

<?php
$start = 1;

$timestart = microtime(1);
for ($i = 0; $i < 1000000; $i++) {
    $result1 = $start * 4;
}
echo "\n";
echo microtime(1) - $timestart;
echo "\n";

$timestart = microtime(1);
for ($i = 0; $i < 1000000; $i++) {
    $result2 = $start << 2;
}
echo "\n";
echo microtime(1) - $timestart;
echo "\n";

这个输出:

0.14027094841003

0.12061500549316

我在网上找到了一个谷歌面试问题(我想申请一个开发人员,但我意识到我做不到),其中一个问题问最快的方法是乘以一个数字。我的第一个想法是使用* 符号,所以我测试了它。

我的问题是,为什么移位比乘法快?

【问题讨论】:

  • 因为乘法需要...乘法...比位移需要更多时间,因为它是一个更复杂的操作?
  • @Dan - 这个问题可能更多地与为什么位移可能或可能不等同于 PHP 中的整数/浮点乘法有关。
  • 参见 en.wikipedia.org/wiki/Multiplication_algorithm#Electronic_usage 声明 To multiply two numbers with n digits using this method, one needs about n2 operations. More formally: using a natural size metric of number of digits, the time complexity of multiplying two n-digit numbers using long multiplication is Θ(n2). 位移是一条指令。
  • 顺带一提,还有more ways to perform multiplication than one might expect——不同的情况下有不同的方法擅长。
  • @drew010; linear-time algorithm is available——假设你有一些表的内存。

标签: php bit-shift multiplication


【解决方案1】:

在 Intel sandybrigde CPU 上,这似乎是一个转变,立即花费大约 1 个时钟周期,而乘法大约需要 3-4 个周期。显然,整个程序的性能不仅受到原始乘法的影响,还受到更多因素的影响,但这足以产生影响。如今,大多数编译器将乘法乘以常数 2^n 优化为移位(编译器编写者喜欢优化您的代码 :)),但 PHP 解释器可能不会。

【讨论】:

  • 这是一个很好的答案。现在我很好奇 PHP 解释器是否优化了 2^n 乘以转换!
【解决方案2】:

因为移位是计算机一直在硬件中执行的操作,所以对于 CPU 来说是轻而易举的事。将任意数字相乘比较困难,因为它不一定使用简单的位移来完成,而是需要实际工作。将一个小整数乘以 4 恰好是与左移 2 相同的操作。但即使编译器/运行时/CPU 将此操作优化为位移位,某些代码首先需要识别 em> 可以通过这种方式进行优化,这比简单的位移本身要多。

不管怎样,这只是更多的工作,因为这两个操作做完全不同的事情,即使某些操作的结果是相同的。

【讨论】:

    【解决方案3】:

    因为位移是一种可以直接在硬件中实现的运算,而硬件很少直接实现乘法运算。乘以 2 的幂可以通过几个简单的逻辑门来实现,而乘以任意被乘数至少需要多次乘以 2 的幂加上彼此叠加的自加操作(5 = 2 * 2 + 1)。我不知道 PHP 语言是否专门通过使用任何可用的低级调用来实现移位操作,但如果没有,我会感到惊讶。

    来源:多年经验 + 计算机科学教育

    【讨论】:

    • 您可能想明确表示您是在谈论硬件效率与 ISA。 x86 和 ARM 都支持硬件中的乘法指令。这几乎不能算作“很少”。我认为您需要定义“直接”的含义。
    • 我不知道 x86 和 ARM 在硬件中支持乘法指令。 “直接在硬件中”是指在硬件中构建的逻辑门,没有任何汇编代码来帮助。例如,可以仅使用硬件来实现加法和递增。我被告知纯硬件乘法可能需要比加法更多的门,并且除了超级计算机之外很少在任何东西中实现。汇编例程可以通过重复加法或其他优化(例如重复位移和自加法)来模拟硬件乘法。
    • @taz:当芯片中有十亿个晶体管时,乘法器只需几千个晶体管并不算多,而移位和加法的性能提升足以证明这一点。很难找到没有内置乘除法的 32 位或 64 位 CPU。
    • @IraBaxter 感谢您提供信息。我怀疑我的导师可能有点落伍了。
    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 2020-01-28
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多