在MATLAB中使用向量标量乘法实现慢速循环

时间:2014-07-10 09:58:40

标签: performance matlab vectorization flops

  

我做错了什么,或者逐个标量的乘法真的如此昂贵? MATLAB(2012版或更高版本)不是以某种方式优化代码以防止这种好奇心吗?

>> tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
Elapsed time is 1.338225 seconds.
>> tic; for i=1:100000; x = sin(i).*[1; 1]; end; toc;
Elapsed time is 1.228331 seconds.
>> tic; for i=1:100000; x = [sin(i); sin(i)]; end; toc;
Elapsed time is 0.073888 seconds.
>> tic; for i=1:100000; tmp=sin(i); x = [tmp; tmp]; end; toc;
Elapsed time is 0.072120 seconds.

您可以指导我在MATLAB中制作FLOPS需要花费他们 所需的时间。

PS。这只是一个示例代码,我所做的是解决颂歌系统,我想在计算所需差异时优化运行时间。以上是让我担心我可能会以非最佳方式做某事。

3 个答案:

答案 0 :(得分:3)

  

“MATLAB(2012版或更高版本)不以某种方式优化代码   防止这种好奇心?“

是的,如果代码在函数 m文件中,由于JIT编译器,它会这样做 (及时编译)和/或加速器

然而,正如评论和其他答案中所提到的,如果可能的话,矢量化通常仍然是更好的选择

直接命令行:

tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;
Elapsed time is 1.795528 seconds.
Elapsed time is 1.606081 seconds.
Elapsed time is 0.072672 seconds.
Elapsed time is 0.065904 seconds.

在函数中;

[x1,x2,x3,x4]=foo();
Elapsed time is 0.029698 seconds.
Elapsed time is 0.035248 seconds.
Elapsed time is 0.064080 seconds.
Elapsed time is 0.054499 seconds.

将函数foo保存为:

function [x1,x2,x3,x4]=foo()

tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;

end

修改

在尝试查找支持上述声明的文档时,我意识到我犯了一个错误,它也加速了脚本m文件,因此上面编辑了函数

在剧本中;

fooscript;
Elapsed time is 0.033536 seconds.
Elapsed time is 0.033720 seconds.
Elapsed time is 0.066050 seconds.
Elapsed time is 0.058428 seconds.

脚本fooscript包含:

tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;

遗憾的是,JIT和加速器(如果有的话)上没有大量的文档。 但是,为了进行比较,您可以使用feature('accel','on'/'off')feature('jit','on'/'off')禁用JIT或加速。 (注意:禁用accel也会禁用jit,因为它似乎是accel的一部分。)

如果禁用accel,性能改进会降低,但功能和脚本性能仍然相似,并且两者仍然明显快于命令行。

禁用JIT对性能没有明显影响,因此原始声明是错误的。

答案 1 :(得分:2)

你的for循环正在杀死你

这是我的机器上代码的时间安排:

tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x = [sin(i); sin(i)]; end; toc;

经过的时间是0.799754秒 经过时间为0.819284秒 经过的时间是1.90613秒。


如果你矢量化它,你得到

t=1:100000; 

tic;     t=1:100000;   x = sin(t).'*[1; 1].'; toc;

tic;     t=1:100000;   sin(t).*[1;1] ; toc;

tic;     t=1:100000;  [sin(t);sin(t)] ; toc;

经过的时间是0.015624秒 经过时间为0.0380838秒 经过时间为0.0322251秒。

tmp=sin(i); x = [tmp; tmp];[sin(t);sin(t)];

相同

答案 2 :(得分:0)

MATLAB针对涉及矩阵和向量的操作进行了优化。在许多情况下,您可以重写基于循环的,面向标量的代码,以使用MATLAB矩阵和向量运算,这个过程称为向量化。矢量化代码的运行速度通常比包含循环的相应代码快得多。

例如:

>> tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
Elapsed time is 2.859756 seconds.

可以使用矩阵运算执行相同的计算:

>> tic; x = [1;1]*sin(1:100000); toc
Elapsed time is 0.007731 seconds.