3

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

>> 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。这只是一个示例代码,我所做的是解决 odes 系统,我想在计算所需的差异时优化运行时间。以上让我担心我可能会以非最佳方式做某事。

4

3 回答 3

3

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

是的,如果代码在函数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')但是,为了比较,您可以使用and禁用 JIT 或加速feature('jit','on'/'off')。(注意:禁用 accel 也会禁用 jit,因为它似乎是 accel 的一部分。)

如果禁用加速,性能改进会降低,但是函数和脚本性能仍然相似,并且都比命令行快得多。

禁用 JIT 对性能没有明显影响,所以原来的说法是错误的。

于 2014-07-10T11:59:38.843 回答
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)];

于 2014-07-10T10:32:57.933 回答
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.
于 2014-07-10T10:36:40.237 回答