一段时间以来,我一直在处理logit,我需要使用内置的exp()函数。与使用具有相同矩阵较小块的for循环相比,对于大型矩阵而言,这似乎运行起来更慢。
在Matlab文档和其他几种形式中,始终建议对代码进行矢量化处理以加快速度。但这似乎并非如此。
n = 32;
rows = 50000;
cols = 32;
a = rand(n*rows, cols);
b = rand(rows, cols);
% in a loop
tic
for i=1:n
d = exp(b);
end
toc
% big matrix
tic
d = exp(a);
toc
我希望第一个tic-toc慢于第二个。但是我得到的输出如下:
Elapsed time is 0.335781 seconds.
Elapsed time is 0.390191 seconds.
关于这种情况的任何想法都会有所帮助。
编辑1 假设我这样编辑我的代码,以便每次都使用随机值:
n = 32;
rows = 50000;
cols = 32;
% in a loop
tic
for i=1:n
d = exp(rand(rows, cols));
end
toc
% big matrix
tic
e = exp(rand(n*rows, cols));
toc
return
我仍然得到:
Elapsed time is 0.745808 seconds.
Elapsed time is 0.847162 seconds.
答案 0 :(得分:0)
您没有进行公平的比较:“循环”用例使用更少的内存,多次读取相同的较小数组,而“大矩阵”用例则需要读取更大的内存块并写入更大的内存块。从主内存读取是一个瓶颈,因此能够利用缓存有助于加快“循环”代码的速度。
这是一个比较公平的比较:
rows = 32*50000;
cols = 32;
a = rand(rows, cols);
% in a loop
tic
d = zeros(size(a));
for i=1:cols
d(:,i) = exp(a(:,i));
end
toc
% big matrix
tic
d = exp(a);
toc
我看到了(MATLAB R2019a Online):
Elapsed time is 0.208699 seconds.
Elapsed time is 0.140489 seconds.
所以循环慢。但这并没有那么慢。在过去的15年左右的时间里,MATLAB一直在稳步提高其JIT。在他们引入JIT之前,循环代码的速度很容易慢100倍左右。
注意::始终确保至少运行两次计时脚本,并丢弃最初的计时。第一次运行某些代码时,JIT需要对其进行编译,从而增加了测量的时间。
关于编辑1 :
这里,在“循环”情况下,您仍在处理较小的数组。除了在循环内移动了rand
调用之外,没有太大的变化。临时记忆被重新使用。