0

如果这太像“做我的功课”问题,我深表歉意。我有点卡住了,这是我要去的地方。这不是我编写的代码,但我现在正在维护它。

我有一个工具可以在糟糕的一天运行大约 8 个小时。我今天介绍了它。91.4% 的运行时间在一个子函数中,而这 70% 的时间都花在了这一行代码上。由于在 3-4 个嵌套的 for 循环内(不可避免),这在分析运行中被有效调用了 60000 次

    testincrease = ones(183,3021)*.02;
    cRange = (0:177)'; %fix broken syntax highlighting --> '
    pRate = ones(183,3021)*.02;
    lengthA = 0;
    lengthP = 178;
    nSim = 3021;

    tic
    for i  = 1:100
    v_F = @(adj_N,adj_I) (((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))).^...
                repmat([cRange+0.5],[1 nSim]))...
                ./ ...
                (repmat(((1+adj_I+testincrease(lengthA+1,:))./(1 + adj_N+ pRate(lengthA+1,:))), [lengthP 1]).^...
                repmat([repmat(cRange(1), [lengthP 1])], [1 nSim]));
    v=v_F(0,0);
    end
    toc

目前的想法:

我认为也许我可以使用 bsxfun 代替 repmat (目前正在尝试)

当 cRange(1) = 0 时(就像在我的测试数据的一部分中所做的那样——我放在这里的部分),后半部分只是简单地除以 1——一种昂贵且毫无意义的计算。所以我想围绕这个使用'if'子句来避免不必要的计算。

调用另一种语言——这对我来说是全新的。应该会去试试吧。显然可以轻松访问 java,并且还可以创建 mex 文件。在后一种情况下,我认为传递数据的开销将非常昂贵,除非我重写大量代码而不仅仅是这一行。

如果您有任何其他想法,我将不胜感激。如果没有,我会继续做更多的研究。

编辑:刚刚注意到函数 repmats 的最后一行是完全没有必要的,因为您可以 .^ 通过标量值而无需将其更改为矩阵

二次编辑:这是到目前为止的样子。节省 30%。

tic
for i  = 1:100
    if cRange(1) == 0

        v_F = @(adj_N,adj_I) bsxfun(@power,((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))),cRange+0.5);

    else
        v_F = @(adj_N,adj_I) bsxfun(@power,((1+ adj_I+ testincrease(cRange+1,:))./(1 + adj_N + pRate(cRange+1,:))),cRange+0.5)...
            ./ ...
            (repmat(((1+adj_I+testincrease(lengthA+1,:))./(1 + adj_N+ pRate(lengthA+1,:))).^cRange(1), [lengthP 1]));

    end
    v=v_F(0,0);
end
AllChange = toc;

但由于某种原因,在 2011a 年加速它的 bsxfun 变化在我们编译的 2008 年减慢了它。臭虫。

4

1 回答 1

2

建议 1 - 尝试在没有 repmat 的情况下重写代码:

repmat进行大量的内存分配和内存副本......因此,如果您将代码重写为相同的功能但不使用repmat它可能会大大提高速度。(仅供参考......一行代码有4个repmat函数调用......其中一个repmat调用有repmat它的内部......这将非常慢。)

建议 2 - 尝试重写单行:

将这个 MASSIVE 单行代码重写为多行。然后重新运行您的探查器。然后,您将能够更清楚地看到导致减速的确切原因!然后你可以修复那段代码。(专业提示:由于各种原因(可读性、调试、性能等),大型单行有时并不是代码中最好的东西)——Trevor Boyd Smith 17 秒前编辑

建议 3 - 利用并行化:

我认为您的一行代码中的大多数操作都可以并行化。所以我建议先试试Matlab的parallel toolboo。然后,如果这还不够快...尝试通过外部第三方 Matlab GPU 加速软件包(如Jacket )使用 GPU 加速。


(免责声明:这些是一般提示......我自己还没有尝试过这些......但我会在有时间的时候尝试。)

于 2012-07-20T17:46:17.140 回答