簡體   English   中英

乘法如何比向左移位快?

[英]How can the multiplication be faster than shifting bits to the left?

眾所周知,向左移位比乘法快,因為桶形移位器直接在硬件中實現。 因此,這個簡單的基准應該是錯誤的:

$start = 1;

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

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

因為我執行了多次,並且總是乘起來比向左移位快。 例如:

0.73733711242676

0.71091389656067

因此,或者基准測試是錯誤的,或者PHP解釋器正在此處執行某些操作。 該測試由在Ubuntu中運行的PHP 7.0.32執行:

PHP 7.0.32-0ubuntu0.16.04.1(cli)(NTS)

CPU:3.20GHz時的Intel(R)Core(TM)i5-4460 CPU

編輯:

在具有幾乎相同的CPU(Intel(R)CoreTM i5-4460S CPU @ 2.90GHz)的Windows盒中執行它,結果如預期的那樣:

0.24960112571716

0.28080010414124

這種情況下的PHP版本是不同的:

PHP 7.1.19(CLI)(內置:2018年6月20日23:24:42)(ZTS MSVC14(Visual C ++ 2015)x64)

您關於硬件的推理基本上是無關緊要的。 您正在使用一種解釋語言,其中大部分成本是解釋器開銷。

每個循環的一個asm版本每個時鍾可以運行1次(假設有固定計數的移位),因此(在3GHz CPU上)僅進行100k次迭代就需要0.033毫秒(即0.000033秒),比PHP的速度快250倍。


而且,解釋循環必須使用可變計數移位(因為它不能將移位計數JIT編譯到機器代碼的立即數中),實際上這對於Intel CPU的吞吐量(3微秒)而言更加昂貴x86傳統行李(標志語義)。 AMD CPU甚至具有可變移位計數,也具有單uup移位。 shl reg, cl vs. shr reg, imm8 )。 參見INC指令與ADD 1:有關系嗎? 進一步了解為什么shl reg,cl在Sandybridge家族上為3 uops,以及如何通過標志創建虛假依賴關系)

在Intel Sandybridge系列和AMD Ryzen上,整數乘法是1 uop,每時鍾1個吞吐量,3個周期延遲。 我每2個時鍾在AMD Bulldozer系列上運行一次,但未完全流水線化。 因此,是的,乘法具有更高的延遲,但是它們都已完全流水線化以提高吞吐量。 您的循環會丟棄結果,因此沒有循環承載的依賴關系鏈,因此延遲是無關緊要的(並且由於亂序執行而被隱藏)。

但是,這個微小的差異(額外的2個ouop)不足以解決所測得的差異。 實際的移位或乘法運算僅是循環總周期的1/250。 您說切換循環的順序不會改變結果,因此在CPU加速到最大時鍾速度之前,這不僅僅是預熱效果。

您沒有提到正在運行的CPU微體系結構,但是答案可能並不取決於移位與乘法指令的解碼方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM