Performance for循环中的计算速度

Performance for循环中的计算速度,performance,matlab,random,for-loop,matrix,Performance,Matlab,Random,For Loop,Matrix,我在matlab中编写了一个小循环来生成一个随机的NxN矩阵。循环是 tic for i=1:10000 u=rand(1,10000); tau(i,:)=d.*(u(1,:)-0.5); end toc 我第一次只试过一次循环程序 u=rand(1,10000); tau=d.*(u(1,:)-0.5); 这让我在0.000169秒内得到了头。我假设循环大约需要1.69秒。没有,花了555.018280美元,粉丝们都疯了 是否有 a) 速度与迭代次数不成线

我在matlab中编写了一个小循环来生成一个随机的NxN矩阵。循环是

tic
for i=1:10000
    u=rand(1,10000);
    tau(i,:)=d.*(u(1,:)-0.5);
end
toc
我第一次只试过一次循环程序

    u=rand(1,10000);
    tau=d.*(u(1,:)-0.5);
这让我在0.000169秒内得到了头。我假设循环大约需要1.69秒。没有,花了555.018280美元,粉丝们都疯了

是否有
a) 速度与迭代次数不成线性关系的原因?
b) 为什么要花这么长的时间做很多次例行公事的原因

c) 一种加速这个的方法(我实际上想生成更大的矩阵),例如一个更好的循环,或者给我一个类似的1'000'000x1'000'000矩阵?

你必须首先预先分配你的矩阵
tau
,即

  tau = zeros(10000,10000);
否则,matlab将在有足够可用内存的区域(=>找到有足够可用空间的区域+硬拷贝)连续重新分配它

一般来说,将整个过程矢量化可以获得更好的性能:

 u=rand(10000,10000);
 tau=d.*(u-0.5);


编辑:最重要的是,在下面的评论中听取罗迪明智的建议。(在任何情况下,我假设
rand(a,b)
的运行速度比
a
rand(1,b)
的串行执行速度略快。

一个明显的可能性是内存访问量。测试循环的内存可能完全在缓存中,但是由完整循环写入的内存需要大量的主内存访问

这是一个可验证的假设:时间写下整个矩阵,而不做算术


如果我理解Matlab索引,您可以更快地切换维度,这样您就可以编写位于同一列而不是同一行中的块。将u转换为循环外的列向量也可能有所帮助。一般来说,应尽可能按内存顺序访问大型矩阵。

尝试预分配
tau
。有一个名为“加速MATLAB应用程序”的网络研讨会。有一些关于大型矩阵以及如何处理它们的信息。更好地防止双重内存分配(注意,
u
是800兆字节):
tau=d.*(rand(10000)-0.5)
。或者,如果
size(d)=[1 10000]
,则使用
tau=bsxfun(@times,d,rand(10000)-0.5)
。峰值内存仍将保持不变,但是,在此分配之后,1.6GB峰值中的800MB将被释放。或者:之后只需发出一个
clear u
。@RodyOldenhuis因此主要的要点是执行
tau=d.*(rand(1000010000)-0.5),对吗?。顺便说一句,
bsxfun
版本快了吗?可能不快,但当
d
的大小仅适用于循环解决方案(
size(d)==[1 10000]
)实际上tau=d.*(rand(1000010000)-0.5)时,它很有用;在32秒内成功,这是一个巨大的进步!谢谢!