登录论坛

查看完整版本 : 每列的MATLAB矩阵乘法与for循环


poster
2019-12-14, 20:13
当将两个矩阵相乘时,我尝试了以下两个选项:

1)

res = X*A; 2)

for i = 1:size(A,2) res(:,i) = X*A(:,i); end 我为这两个资源预分配了内存。令人惊讶的是,我发现选项2更快。

有人可以解释这是怎么回事吗?

编辑:我试过

K=10000; clear t1 t2 t1=zeros(K,1); t2=zeros(K,1); for k=1:K clear res x = rand(100,100); a = rand(100,100); tic res = x*a; t1(k) = toc; end for k=1:K clear res2 res2 = zeros(100,100); x = rand(100,100); a = rand(100,100); tic for i = 1:100 res2(:,i) = x*a(:,i); end t2(k) = toc; end

回答:

我相信我可以了解两种方法之间的时间变化以及人们获得相对速度不同的原因。

在Matlab 2008a版本(或该版本附近的版本)之前,for循环在任何Matlab代码中都受到了很大的打击,因为解释器(在可读性强的脚本和较低级别的代码实现之间的一层)必须重新解释该代码。每次通过for循环进行编码。

自该版本发布以来,解释器逐渐变得更好,因此,当运行现代版本的Matlab时,解释器可以查看您的代码并说“啊哈!我知道他在做什么,让我稍加优化一下”并避免否则,通过重新解释代码将遭受打击。

我希望执行矩阵乘法的两种方式可以在相同的时间内求值,为什么for循环实现运行得更快是因为解释器的优化中有些细节,我们仅仅是凡人都不知道。

我们应该从中吸取一个广泛的教训,即并非所有版本都是平等的。我确实使用两个Matlab附加组件SimBiology和Parallel Computing Toolboxes处理了几个前沿案例,这两者(特别是如果您希望它们一起工作)都取决于版本的执行速度,并且有时会其他稳定性问题。因此,我保留了Matlab的三个最新发行版,将测试从每个版本中获得的答案是否相同,如果发现某些功能方面的问题,我有时会回滚到较早的版本。对于大多数人来说,这可能算是过高了,但是可以让您了解版本差异。

希望这可以帮助。

编辑:

为了澄清,代码矢量化仍然很重要。但是给定一个像这样的脚本:

x_slow = zeros(1,1e5); x_fast = zeros(1,1e5); tic; for i=1:1e5 x_slow(i) = log(i); end time_slow = toc; % evaluates for me in .0132 seconds tic; x_fast = log(1:1e5); time_fast = toc; % evaluates for me in .0055 seconds 在过去的几个版本中,基于解释器的改进,减少了time_slow和time_fast之间的差异。我所看到的示例是在2000a与2008b上进行的,但我对此记忆犹新。

Oli和Yuk解决了其他事情。 time_1和time_2通常在以下方面有所不同:

tic; x = log(1:1e5); time_1 = toc tic; x = log(1:1e5); time_2 = toc 因此,根据内存x的位置(高速缓存或否),对一百万个评估与一个评估进行的测试是有价值的。

希望这会再次有所帮助。



更多&回答... (https://stackoverflow.com/questions/4916026)