什么时候矢量化比循环更好或更差? [英] When does vectorization is a better or worse solution than a loop?

查看:95
本文介绍了什么时候矢量化比循环更好或更差?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Matlab中,我试图对代码进行矢量化处理以缩短仿真时间.但是,我得到的结果是我降低了整体效率.

In Matlab, I am trying to vectorise my code to improve the simulation time. However, the result I got was that I deteriorated the overall efficiency.

要了解这种现象,我创建了3个不同的函数,它们执行相同的操作但使用不同的方法:

To understand the phenomenon I created 3 distinct functions that does the same thing but with different approach :

主文件:

clc,
clear,

n = 10000;
Value = cumsum(ones(1,n));

NbLoop = 10000;

time01 = zeros(1,NbLoop);
time02 = zeros(1,NbLoop);
time03 = zeros(1,NbLoop);

for test = 1 : NbLoop

    tic
    vector1 =  function01(n,Value);
    time01(test) = toc ;

    tic
    vector2 =  function02(n,Value);
    time02(test) = toc ;

    tic
    vector3 =  function03(n,Value);
    time03(test) = toc ; 

end

figure(1)
hold on

plot( time01, 'b')
plot( time02, 'g')
plot( time03, 'r')

函数01:

function vector =  function01(n,Value)

vector = zeros( 2*n,1);
for k = 1:n
    vector(2*k -1) =  Value(k);
    vector(2*k) =  Value(k);
end

end

功能02:

function vector =  function02(n,Value)

vector = zeros( 2*n,1);
vector(1:2:2*n) = Value; 
vector(2:2:2*n) = Value; 

end

函数03:

function vector =  function03(n,Value)

MatrixTmp = transpose([Value(:), Value(:)]);
vector = MatrixTmp (:);

end

蓝色图对应于for-循环.

The blue plot correspond to the for - loop.

n = 100:

n = 10000:

n = 10000:

当我使用n = 100运行代码时,更有效的解决方案是使用for循环的第一个函数. 当n = 10000时,第一个功能的效率降低.

When I run the code with n = 100, the more efficient solution is the first function with the for loop. When n = 10000 The first function become the less efficient.

  • 您是否有办法知道如何以及何时用矢量化对象正确替换for循环?
  • 使用巨大维度的数组进行索引搜索有什么影响?
  • Matlab是否以不同的方式计算尺寸为3或更高的数组,而不是尺寸为1或2的数组?
  • 是否有一种聪明的方法来替换使用迭代结果进行下一次迭代的while循环?

推荐答案

使用 MATLAB在线我看到了一些东西不同:

Using MATLAB Online I see something different:

n            10000       100
function01   5.6248e-05  2.2246e-06
function02   1.7748e-05  1.9491e-06
function03   2.7748e-05  1.2278e-06
function04   1.1056e-05  7.3390e-07  (my version, see below)

因此,循环版本始终是最慢的.方法2对大型矩阵更快,方法3对小型矩阵更快.

Thus, the loop version is always slowest. Method #2 is faster for very large matrices, Method #3 is faster for very small matrices.

原因是方法#3制作了2个数据副本(transpose或矩阵产生了一个副本),如果有很多数据,那就不好了.方法2使用索引编制,索引编制很昂贵,但不像两次复制大量数据那样昂贵.

The reason is that method #3 makes 2 copies of the data (transpose or a matrix incurs a copy), and that is bad if there's a lot of data. Method #2 uses indexing, which is expensive, but not as expensive as copying lots of data twice.

我建议改为使用此函数(方法4),该函数仅转置向量(基本上是免费的).这是对方法3的简单修改:

I would suggest this function instead (Method #4), which transposes only vectors (which is essentially free). It is a simple modification of your Method #3:

function vector = function04(n,Value)
vector = [Value(:).'; Value(:).'];
vector = vector(:);
end

您是否有办法知道如何以及何时用矢量化对象正确替换for循环?

Do you have a way to know how and when to properly replace a for-loop by a vectorised counterpart?

通常,如果没有大的中间矩阵,矢量化代码总是更快.对于小数据,您可以更主动地进行矢量化;对于大数据,有时由于降低了内存压力,因此循环效率更高.这取决于向量化需要什么.

In general, vectorized code is always faster if there are no large intermediate matrices. For small data you can vectorize more aggressively, for large data sometimes loops are more efficient because of the reduced memory pressure. It depends on what is needed for vectorization.

使用巨大维度的数组进行索引搜索有什么影响?

What is the impact of index searching with array of tremendous dimensions?

这是指诸如d = data(data==0)之类的操作.就像其他所有内容一样,这对于小数据有效,而对大数据则不太有效,因为data==0是与data相同大小的中间数组.

This refers to operations such as d = data(data==0). Much like everything else, this is efficient for small data and less so for large data, because data==0 is an intermediate array of the same size as data.

Matlab是否以不同的方式计算尺寸为3或大于尺寸1或2的数组?

Does Matlab compute in a different manner an array of dimensions 3 or higher than a array of dimension 1 or 2?

不,一般而言.诸如sum之类的功能以与维数无关的方式需要引用来实现.

No, not in general. Functions such as sum are implemented in a dimensionality-independent waycitation needed.

是否有一种聪明的方法来替换使用迭代结果进行下一次迭代的while循环?

Is there a clever way to replace a while loop that use the result of an iteration for the next iteration?

这在很大程度上取决于所执行的操作.经常使用诸如cumsum之类的功能来矢量化这种类型的代码,但并非总是如此.

It depends very much on what the operations are. Functions such as cumsum can often be used to vectorize this type of code, but not always.

这是我的计时代码,希望它能显示如何正确使用timeit:

This is my timing code, I hope it shows how to properly use timeit:

%n = 10000;
n = 100;
Value = cumsum(ones(1,n));

vector1 = function01(n,Value);
vector2 = function02(n,Value);
vector3 = function03(n,Value);
vector4 = function04(n,Value);
assert(isequal(vector1,vector2))
assert(isequal(vector1,vector3))
assert(isequal(vector1,vector4))

timeit(@()function01(n,Value))
timeit(@()function02(n,Value))
timeit(@()function03(n,Value))
timeit(@()function04(n,Value))

function vector = function01(n,Value)
vector = zeros(2*n,1);
for k = 1:n
    vector(2*k-1) = Value(k);
    vector(2*k) = Value(k);
end
end

function vector = function02(n,Value)
vector = zeros(2*n,1);
vector(1:2:2*n) = Value; 
vector(2:2:2*n) = Value; 
end

function vector = function03(n,Value)
MatrixTmp = transpose([Value(:), Value(:)]);
vector = MatrixTmp(:);
end

function vector = function04(n,Value)
vector = [Value(:).'; Value(:).'];
vector = vector(:);
end

这篇关于什么时候矢量化比循环更好或更差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆