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

时间:2013-02-27 10:14:09

标签: 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[$j]);
            }
        }

我想知道是否有办法让这段代码运行得更快?

3 个答案:

答案 0 :(得分: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]);
    }
}

答案 1 :(得分: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来检索矩阵的行来加快速度。但请注意,这会按照这些行数组添加到矩阵的顺序迭代行集!如果矩阵和向量之间的顺序不同,结果将全部错误。所以,可能不是那么可靠的事情,因为它很容易打破......

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

答案 2 :(得分:0)

PHP数组趋于缓慢,这是对散列机制的致敬。 PHP array performance。如果您有办法预先确定向量的大小,则可以展开循环并避免使用数组。如果您的代码是整个代码,那么这对您无济于事,因为$transposed_matrix中的每个项目只会被点击一次,您可以使用{{1}来减少$vector上的点击次数Atze Kaputnik概述的技术。因此,您最终会将数组参数中的内容复制到局部变量中,然后进行计算,然后再将其复制回来......这将超过性能增益。

最后,您所能做的就是切换到完全不同的优化方法:JIT编译器,如HipHop或编译语言。 C中的相同循环可能以大约10到100倍的速度运行,减去分叉该过程的时间。