【问题标题】:computational speed in a for loopfor循环中的计算速度
【发布时间】:2012-11-07 11:23:47
【问题描述】:

我在 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 秒内给了我 tau。我假设循环将花费大约 1.69 秒。它没有,粉丝们疯狂地花了 555.018280 秒。

有吗
a) 速度与迭代次数不呈线性关系的原因是什么?
b) 为什么多次执行该例程需要如此更长的时间
c)一种加快这个速度的方法(我实际上想生成更大的矩阵),例如一个更好的循环或给我的方法,比如说,一个 1'000'000x1'000'000 相同类型的矩阵?

【问题讨论】:

标签: performance matlab random for-loop matrix


【解决方案1】:

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

  tau = zeros(10000,10000);

否则matlab会不断地在有足够空闲内存的区域重新分配它(=>找到一个有足够空闲空间的区域+硬拷贝)。

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

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

编辑:最重要的是,请在下面的评论中听取 Rody 的明智建议。 (无论如何,我假设rand(a,b) 会比a 串行执行rand(1,b) 运行得快一点。

【讨论】:

  • 更好地防止双内存分配(注意,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(10000,10000)-0.5);,对吧?顺便说一句,bsxfun 版本更快吗?
  • 可能不会更快,但当d 的大小仅适用于循环解决方案时很有用(size(d)==[1 10000]
  • 确实 tau=d.*(rand(10000,10000)-0.5);在 32 秒内完成,进步很大!谢谢大家!
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2015-12-27
    • 1970-01-01
    相关资源
    最近更新 更多