【问题标题】:Are single loops or dense loops more computationlly efficent in matlab?在 matlab 中,单循环或密集循环的计算效率更高吗?
【发布时间】:2014-06-28 01:54:55
【问题描述】:

我目前正在编写代码以使用有限差分矩阵方法实现 3D 稳态热方程的数值近似。这涉及将二阶 PDE 分解为矩阵 A 并求解 Ax=b。其中 x 是每个指定网格点的温度。可在此处找到有关此类问题的更多信息:

http://people.nas.nasa.gov/~pulliam/Classes/New_notes/Matrix_ODE.pdf

为了完成这个问题,我用一个 2D 数组表示 3D 矩阵 A,它使用以下形式的索引函数调用 1D 数组 b 中的值:

i+(j-1)*Nx+Nx*Ny*(k-1)

对于 3D 矩阵的第 (i,j,k) 个元素,其中 Nx, Ny, Nz 是 x,y,z 坐标中的点数。为了创建矩阵 A 和 b 最终需要进行大量循环计算,我想知道运行这些循环的计算效率最高且内存消耗更少的方法是什么,即使用类似

for j=1:Ny
    for i=2:Nx-1
        b(i+(j-1)*Nx)=D4;    
    end
end


for j=1:Ny
    for i=2:Nx-1
        b(i+(j-1)*Nx+Nx*Ny*(Nz-1))=D3;   
    end
end

或者我应该将它们压缩成一个循环,例如:

for j=1:Ny
    for i=2:Nx-1
        b(i+(j-1)*Nx)=D4;
        b(i+(j-1)*Nx+Nx*Ny*(Nz-1))=D3;    
    end
end

我已经预先分配了数组 A 和 b。是否也有一种矢量化的方式来做到这一点?

【问题讨论】:

    标签: matlab memory for-loop vectorization


    【解决方案1】:

    假设 NxNyNzD3D4 是标量,并且您使用预分配 b 与零,您可以尝试这种矢量化方法 -

    I = 2:Nx-1; %// Vectors to represent i
    J = 1:Ny; %// Vectors to represent j
    
    ind1 = bsxfun(@plus,I,[(J-1)*Nx]'); %//' Indices, 1st set of nested loops
    ind2 = bsxfun(@plus,I,[(J-1)*Nx+Nx*Ny*(Nz-1)]'); %//' Indices, 2nd set of loops
    
    b(ind1) = D4; %// Assign values for 1st set
    b(ind2) = D3; %// Assign values for 2nd set
    

    【讨论】:

      【解决方案2】:

      第二种方法应该稍微快一些,因为它执行相同数量的计算而循环变量的增量更少。您可以查看 MATLAB 的内置秒表命令 tictoc 来为您的代码计时。 http://www.mathworks.com/help/matlab/ref/tic.html

      更多的向量化可能是可能的,但我需要更多地了解包含D3D4 的数组的格式。 reshape() 函数可能会有所帮助。

      【讨论】:

      • D3 和 D4 只是常数,此公式适用于部分边界条件。感谢您的帮助
      猜你喜欢
      • 2022-11-10
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      • 2012-05-31
      • 2019-11-06
      • 1970-01-01
      相关资源
      最近更新 更多