2013-02-27 123 views
0

我有這個代碼執行一個用php編寫的矩陣向量乘法。更快的矩陣向量乘法實現[並行計算]

這裏有一個片段:

for($i = 0; $i < sizeof($transposed_matrix); $i++) { 
      $vector[$i] = 0; 
      for($j = 0; $j < sizeof($new_vector); $j++) { 
       $vector[$i] += ($transposed_matrix[$i][$j] * $new_vector[$j]); 
      } 
     } 

我想知道是否有什麼辦法,使這個代碼運行得更快?

+0

將循環外的sizeof()存儲在變量中。因爲每個循環都調用sizeof()。另外,使用++ $ i而不是$ i ++。預增量快於後增量。 – Tjoene 2013-02-27 10:21:47

+0

如果您想要進行嚴肅的高性能算術,請選擇PHP以外的語言。從慢語言開始,就是在腳下開槍。 (你可以以某種方式從PHP調用C)。 – 2013-02-28 01:48:46

+0

謝謝艾拉。我現在試圖橋接PHP和C/JAVA/SciLab – asleighna 2013-02-28 03:12:01

回答

0

一個優化將是for前計數:

$size = sizeof($transposed_matrix); 
$size2 = sizeof($new_vector); 
for($i = 0; $i < $size; $i++) { 
    $vector[$i] = 0;   
    for($j = 0; $j < $size2; $j++) { 
     $vector[$i] += ($transposed_matrix[$i][$j] * $new_vector[$j]); 
    } 
} 
0

PHP沒有給你足夠的控制了一些嚴重的優化。提議的改進可能會產生相對較小的影響,除非您將巨大的矩陣和向量相乘(在這種情況下,您不應該首先使用PHP)。

除了預先計算的尺寸和使用預增量計數器(由Tjoene所建議的),使用的和的臨時變量中的內循環,像這樣:

$sum = 0; 
for ($j = 0; $j < $numCols; ++$j) { 
    $sum += $matrix[$i][$j] * $vector[$j]; 
} 
$vector[$i] = $sum; 

這將避免計算$ vector中正確的目標位置多次。

可能通過將矩陣數據存儲在單個平面數組中而不是您使用的嵌套結構來實現最大的性能增益。只是在連接矩陣的行,你可以通過它的元素採用單一指標像這樣運行:

for ($i = 0, $n = 0; $i < $numRows; ++$i, ++$n) 
{ 
    $sum = 0; 
    for ($j = 0; $j < $numCols; ++$j) { 
     $sum += $matrix[$n] * $vector[$j]; 
    } 
    $vector[$i] = $sum; 
} 

這當然會,只是速度的東西,如果你沒有轉換到這個矩陣佈局在實際乘法之前。

如果你不想改變矩陣佈局,你可以通過在外層循環中使用foreach來檢索矩陣的行。但是,請注意,它按照將這些行數組添加到矩陣的順序遍歷這組行!如果矩陣和向量之間的順序不同,結果將會全部錯誤。所以,可能不是這樣可靠的事情,因爲它打破了很容易...

哦,你可以隨時嘗試部分展開循環(S)。

0

PHP數組有一個緩慢的趨勢,這是對哈希機制的致敬。 PHP array performance。如果您有辦法預先確定矢量的大小,可以展開循環並避免使用數組。如果您的代碼是整個代碼,但這並不會對您有所幫助,因爲$transposed_matrix中的每個項目只會被擊中一次,並且您可以使用Atze Kaputnik概述的$sum技術減少$vector上的點擊次數。所以你最終會將數組參數中的東西複製到局部變量中,然後計算並複製回來......這不僅會影響性能增益。最後,你所能做的就是切換到完全不同的優化方法:JIT編譯器如HipHop或編譯語言。 C中的相同循環可能以10到100倍的速度運行,減去分叉該進程的時間。

+0

如果性能確實非常重要,我現在試圖將PHP橋接到c/java/scilab – asleighna 2013-02-28 03:09:44

+1

,請使用C.首先,有多個高度優化的並行處理庫可用。主要原因在於,從PHP派生出一個C調用會比開發一個Java客戶端引入更少的開銷。我對Scilab沒有經驗,但我期望它的效率比C低。編輯:我剛剛發現,你可以從PHP調用一個C DLL而不分叉。這可能是最有希望的路徑。 – Hazzit 2013-02-28 12:31:02