Matlab优化

Matlab优化,matlab,optimization,bsxfun,Matlab,Optimization,Bsxfun,如果这太像一个“做我的家庭作业”的问题,我会道歉。我有点卡住了,这是我该去的地方。这不是我写的代码,但我现在正在维护它 我有一个工具,在糟糕的一天运行大约8小时。我今天分析了它。91.4%的运行时间在一个子函数中,其中70%的时间花在这一行代码上。由于在3-4个嵌套for循环内(不可避免),因此在分析运行中有效地调用了60000次 目前的想法: 我想也许我可以用bsxfun代替repmat(目前我正在尝试) 当cRange(1)=0时(就像我在测试数据的一部分中所做的那样——我在这里放的部分),

如果这太像一个“做我的家庭作业”的问题,我会道歉。我有点卡住了,这是我该去的地方。这不是我写的代码,但我现在正在维护它

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

目前的想法:

我想也许我可以用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;

但由于某种原因,在2011年加速的bsxfun更改在2008年的编译中减慢了速度。错误。

建议1-尝试在不使用repmat的情况下重写代码:

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

建议2-尝试重写一行:

将这行庞大的一行改写成多行。然后重新运行探查器。然后,您将能够更清楚地看到到底是什么导致了减速!然后你就可以修复这段代码了。(专业提示:由于各种原因(可读性、调试、性能等),大量的一行程序有时不是代码中最好的东西)-Trevor Boyd Smith 17秒前编辑

建议3-利用并行化:

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



(免责声明:这些是一般性的提示……我自己还没有尝试过其中任何一个……但我会在有时间的时候尝试。)

@TrevorBoydSmith 400万字节=4 MB。这不是真正的“巨大”…对不起我的坏!长夜。。。因为刚出生的宝宝而无法入睡。。。我以为是4GB。您向我们展示的是,在for循环的所有100次迭代中都有相同的输出,您可以通过将for循环更改为i=1:1的
,将输出减少100倍。除此之外,您的嵌套的
repmat
可以从matlab提示符中替换为单个
repmat
,do
doc repmat
,以确保每个维度不需要单独的“repmat”。最后,从您展示的内容来看,每次调用这个for循环时,它都会给出相同的答案。找到答案一次,把它作为常量硬编码,然后继续。这里肯定还有什么你没有告诉我们的?对不起,这是一个非常简单的版本,我想这是最简单的方式来证明我所说的那种事情。这个函数的输入在每次迭代中都会发生巨大的变化,它会被调用58000次。然而,由于这一行代码占运行时间的近50%,因此简单地提高它的速度会产生很大的影响。现在还不清楚为什么必须在for循环中声明函数。在一个之外编程一个并不困难。或者,不要使用匿名函数。制作你自己的函数,也许可以添加一些输入,使事情变得更顺利。我已经在OP中添加了我的“最新”版本。这一点已经考虑在内了。将尝试并配置一个更详细的版本,如你所建议的-好主意!仅供参考,通常我不会在没有亲自尝试这些东西的情况下发布。。。但有时给人一些想法是好的。。。特别是如果有人能在我之前尝试这些想法。
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;