【问题标题】:Matlab slow performance using closuresMatlab使用闭包降低性能
【发布时间】:2013-11-20 15:34:53
【问题描述】:

我正在使用有限元在二维矩形上编写泊松方程的解。为了简化代码,我将基函数的句柄存储在一个数组中,然后遍历这些基函数以创建我的矩阵和右手边。这样做的问题是,即使对于非常粗糙的网格,它也非常慢。对于 9x9 网格(使用 Dirichlet BC,有 49 个节点需要求解),大约需要 20 秒。使用配置文件我注意到大约一半的时间用于访问(而不是执行)我的基本功能。

分析器显示matrix_assembly>@(x,y)bilinearBasisFunction(x,y,xc(k-1),xc(k),xc(k+1),yc(j-1),yc(j),yc(j+1)) (156800 calls, 11.558 sec),自身时间(不执行双线性基代码)超过 9 秒。关于为什么这可能会这么慢的任何想法?

这里是一些代码,如果需要我可以发布更多:

%% setting up the basis functions, storing them in cell array
basisFunctions = cell(nu, 1); %nu is #unknowns 
i = 1;
for j = 2:length(yc) - 1
for k = 2:length(xc) - 1
    basisFunctions{i} = @(x,y) bilinearBasisFunction(x,y, xc(k-1), xc(k),...
        xc(k+1), yc(j-1), yc(j), yc(j+1)); %my code for bilinear basis functions
    i = i+1;
end
end

%% Assemble matrices and RHS
M = zeros(nu,nu);
S = zeros(nu,nu);
F = zeros(nu, 1);

for iE = 1:ne
for iBF = 1:nu
    [z1, dx1, dy1] = basisFunctions{iBF}(qx(iE), qy(iE));

    F(iBF) = F(iBF) + z1*forcing_handle(qx(iE),qy(iE))/ae(iE);

    for jBF = 1:nu
        [z2, dx2, dy2] = basisFunctions{jBF}(qx(iE), qy(iE));

        %M(iBF,jBF) = M(iBF,jBF) + z1*z2/ae(iE);
        S(iBF,jBF) = S(iBF, jBF) + (dx1*dx2 + dy1*dy2)/ae(iE);
    end        
end
end

【问题讨论】:

  • 首先,您在双 for 循环中调用了该行 156,800 次(创建了许多匿名函数),并且每次都使用索引更改参数值!你确定nu 等于(length(xc)-2)*(length(yc)-2) 以避免在单元格basisFunctions 数组中重新分配吗?
  • 是否有任何理由拥有156800个函数而不是一个带有参数(jBF,qx(iE), qy(iE))的函数?
  • @DanielR :只有 49 个函数,每个函数的参数略有不同。当然还有其他方法可以做到这一点,但我在这里做的方式具有可读性很强的优点,我不明白为什么它应该这么慢。
  • 那么 156,800 次做了什么? matrix_assemblybilinearBasisFunction 中的子函数的名称吗?
  • @horchler:是的,我经常这样称呼它,但这是不可避免的,我确实需要大量评估我的基函数。我也调用了 bilinearBasisFunction 156800 次,但根据分析器,这只需要 2 秒。

标签: matlab closures anonymous-function finite-element-analysis


【解决方案1】:

尝试将basisFunctions 从元胞数组更改为常规数组。

您也可以尝试在 jBF 循环中内联对bilinearBasisFunction的直接调用,而不是使用basisFunctions。在 Matlab 中创建和稍后使用匿名函数总是比直接使用目标函数慢。这样代码可能会稍微冗长一些,但会更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    相关资源
    最近更新 更多