gpt4 book ai didi

MATLAB 快速(按分量)矢量运算......非常快

转载 作者:太空宇宙 更新时间:2023-11-03 20:02:24 25 4
gpt4 key购买 nike

我编写 MATLAB 脚本已经有一段时间了,但我仍然不明白它是如何“在幕后”工作的。考虑以下脚本,它以三种不同的方式使用(大)向量进行一些计算:

  1. MATLAB 向量运算;
  2. 简单的 for 循环,以组件方式执行相同的计算;
  3. 应该比 2 更快的优化循环。因为避免了一些分配和一些赋值。

代码如下:

N = 10000000;

A = linspace(0,100,N);
B = linspace(-100,100,N);
C = linspace(0,200,N);
D = linspace(100,200,N);

% 1. MATLAB Operations
tic
C_ = C./A;
D_ = D./B;

G_ = (A+B)/2;
H_ = (C_+D_)/2;
I_ = (C_.^2+D_.^2)/2;

X = G_ .* H_;
Y = G_ .* H_.^2 + I_;
toc
tic
X;
Y;
toc

% 2. Simple cycle
tic
C_ = zeros(1,N);
D_ = zeros(1,N);
G_ = zeros(1,N);
H_ = zeros(1,N);
I_ = zeros(1,N);
X = zeros(1,N);
Y = zeros(1,N);
for i = 1:N,
C_(i) = C(i)/A(i);
D_(i) = D(i)/B(i);

G_(i) = (A(i)+B(i))/2;
H_(i) = (C_(i)+D_(i))/2;
I_(i) = (C_(i)^2+D_(i)^2)/2;

X(i) = G_(i) * H_(i);
Y(i) = G_(i) * H_(i)^2 + I_(i);
end
toc
tic
X;
Y;
toc

% 3. Opzimized cycle
tic
X = zeros(1,N);
Y = zeros(1,N);
for i = 1:N,
X(i) = (A(i)+B(i))/2 * (( C(i)/A(i) + D(i)/B(i) ) /2);
Y(i) = (A(i)+B(i))/2 * (( C(i)/A(i) + D(i)/B(i) ) /2)^2 + ( (C(i)/A(i))^2 + (D(i)/B(i))^2 ) / 2;
end
toc
tic
X;
Y;
toc

我知道人们总是会尝试向量化计算,因为 MATLAB 是基于矩阵/向量构建的(因此,如今,它并不总是最好的选择),所以我期待这样的事情:

C = A .* B;

快于:

for i in 1:N,
C(i) = A(i) * B(i);
end

没有期望的是,即使在上面的脚本中它实际上更快,尽管我使用的第二种和第三种方法只经过一个周期,而第一种方法执行许多向量操作(理论上,每次都是一个“for”循环)。这迫使我得出结论,MATLAB 具有一些魔力,允许(例如):

C = A .* B;
D = C .* C;

比内部有一些操作的单个“for”循环运行更快

所以:

  1. 有什么魔法可以避免第 1 部分执行得如此之快?
  2. 当您写“D= A .* B”时,MATLAB 实际上是使用“for”循环进行组件智能计算,还是只是跟踪 D 包含“bla”和“bla”的一些乘法?

编辑

  1. 假设我想使用 C++(可能使用某些库)实现相同的计算。 MATLAB 的第一种方法会比用 C++ 实现的第三种方法更快吗? (我会自己回答这个问题,给我一些时间。)

编辑 2

根据要求,这里有实验运行时间:

第 1 部分:0.237143

第 2 部分:4.440132其中0.195154用于分配

第 3 部分:2.280640其中0.057500用于分配

没有 JIT:

第 1 部分:0.337259

第 2 部分:149.602017其中0.033886用于分配

第 3 部分:82.167713其中0.010852用于分配

最佳答案

第一个是最快的,因为矢量化代码可以很容易地解释为少量优化的 C++ 库调用。 Matlab 还可以在更高级别对其进行优化,例如,将 G*H+I 替换为优化的 mul_add(G,H,I) 而不是 add (mul(G,H),I) 在其核心。

第二个无法轻松转换为 C++ 调用。它必须被解释或编译。脚本语言最现代的方法是 JIT 编译。 Matlab JIT 编译器不是很好,但这并不意味着它必须如此。我不知道为什么 MathWorks 不改进它。因此 #2 执行得如此之慢以至于 #1 更快,即使它进行了更多的“数学”运算。

Julia 语言的发明是 Matlab 表达式和 C++ 速度之间的折衷。相同的非矢量化代码(juliamatlab)运行速度非常快,因为 JIT 编译非常好。

关于MATLAB 快速(按分量)矢量运算......非常快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16846042/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com