Php 矩阵向量乘法的快速实现[并行计算]

Php 矩阵向量乘法的快速实现[并行计算],php,algorithm,parallel-processing,execution,Php,Algorithm,Parallel Processing,Execution,我有一个用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

我有一个用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]);
            }
        }
for($i=0;$i

我想知道是否有任何方法可以让这段代码运行得更快

一个优化是在
之前对
进行计数:

$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]);
    }
}
$size=sizeof($transposed\u矩阵);
$size2=sizeof($new_向量);
对于($i=0;$i<$size;$i++){
$vector[$i]=0;
对于($j=0;$j<$size2;$j++){
$vector[$i]+=($transposed_矩阵[$i][$j]*$new_向量[$j]);
}
}

PHP没有为某些严重的优化提供足够的控制。所建议的改进可能会产生相对较小的影响,除非您将巨大的矩阵和向量相乘(在这种情况下,您首先不应该使用PHP)

除了预计算大小和使用计数器的预增量(如Tjoene所建议的),在内部循环中使用临时变量求和,如下所示:

$sum = 0;
for ($j = 0; $j < $numCols; ++$j) {
    $sum += $matrix[$i][$j] * $vector[$j];
}
$vector[$i] = $sum;
$sum=0;
对于($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;
}
for($i=0,$n=0;$i<$numRows;++$i,++$n)
{
$sum=0;
对于($j=0;$j<$numCols;++$j){
$sum+=$matrix[$n]*$vector[$j];
}
$vector[$i]=$sum;
}
当然,如果在实际乘法之前不必转换为这种矩阵布局,这只会加快速度

如果不想更改矩阵布局,可以通过在外部循环中使用
foreach
检索矩阵的行来加快速度。但是,请注意,这将按这些行数组添加到矩阵的顺序迭代行集合!如果矩阵和向量之间的顺序不同,则结果都是错误的。所以,这可能不是一件可靠的事情,因为它很容易就打破了


哦,你可以尝试部分地展开循环。

PHP数组有一种缓慢的趋势,这是散列机制的功劳。如果有办法预先确定向量的大小,可以展开循环并避免使用数组。如果您的代码是整个代码,这对您没有帮助,因为
$transposed_matrix
中的每个项目只命中一次,您可以使用Atze Kaputnik概述的
$sum
技术减少
$vector
上的命中次数。因此,您将把数组参数中的内容复制到局部变量,然后计算并复制回。。。这将大大降低性能增益


最后,您所能做的就是切换到一种完全不同的优化方法:类似于JIT编译器或编译语言的JIT编译器。C中的同一个循环可能会以10到100倍的速度运行,减去分叉该进程的时间。

将sizeof()存储在循环外部的变量中。因为每次循环都会调用sizeof()。另外,使用+++$i代替$i++。增量前比增量后快。如果您想做高性能的算术,请选择PHP以外的语言。从一个缓慢的语言开始就是在攻击你自己的脚。(你可以从PHP调用C)。谢谢。我现在正在尝试将PHP与C/JAVA/Scilab连接起来。我现在正在尝试将PHP与C/JAVA/Scilab连接起来。如果性能真的很重要,请使用C。首先,有多个高度优化的并行处理库可用。不过,主要原因是,从PHP派生C调用比派生Java客户机带来的开销要少得多。我没有使用Scilab的经验,但我希望它的效率也低于C。Edit:我刚刚发现,您可以从PHP调用C DLL,而无需任何分叉。这可能是最有希望的途径。