zoukankan      html  css  js  c++  java
  • matlab并行之parafor

    经常用matlab处理大型数据,有时某些数据处理起来可能要几天甚至更久。如果算法已经到最优,那么提高速度的最后方法就是从硬件下手了。在这个什么都开始并行的年代,matlab也提供了并行计算的功能,甚至能用GPU加速。matlab貌似在2010a开始支持并行计算,引入了一个工具箱,叫做parallel computing toolbox.它的使用方法,可以从matlab的帮助获得。

    我现在对matlab并行的研究还只是冰山一角,只研究了它parfor的用法。可以再google中输入matlab parfor,你将得到足够多的资料来了解这是个什么东西,如果你耐心,建议去研究研究matlab 帮助中对parfor的说明。这里我只大概讲一下parfor。parfor就是paralle+for,也就是并行的for循环,怎么个并行法?我理解就是,matlab会弄出几个虚拟的小pc,一个算i=1:30部分循环,一个算i=50:80部分循环,再来一个算i=90:120部分循环,当然数字是我瞎编的,我是想说matlab将一个大循环分成小块,然后这些小块并行计算,最后再合在一起。这样,有一个问题,因为普通的循环是从i=1算到i=100,一个接一个算,如果下一次循环要依赖上一次循环怎么办?如果出现这种情况,那就不能用matlab的parfor了。用parfor的前提条件就是,循环的每次迭代独立,不相互依赖。举个简单的例子,计算1+2+3...+100就可以用parfor,但是如果计算斐波那契数列的前100个数字,那就不能用parfor了。

    parfor就先解释到这里,其实它涉及到的东西远不止这些,而且感觉很令人纠结,如果你的C++很好,那就直接用C++吧!如果你还是想用matlab做并行,那就可以继续向下看看我的一些经验。

    首先我是做图像处理的,1000多个图像,如果直接算可能要算上1天,所以我想用matlab的并行。我们都知道数字图像可以看成矩阵,我们经常用for循环里面再加一个for循环来处理,但是parfor循环不能嵌套。那么原来的

    for i=1:N

      for j=1:M

      end

    end

    就必须改成

    parfor i=1:N

      for j=1:M

      end

    end

    或者

    for i=1:N

      parfor j=1:M

      end

    end

    但是,这都不是最好的方法,因为如果循环的次数太少,并行就显现不出威力来,所以最好的方法是这样:

    for k=1:M*N

      i=mod(k-1,M)+1    %行号

      j=floor((k-1)/M)+1     %列号

    end

    要注意一点的是k是按照列来数的,也就是这样

    1 4 7

    2 5 8

    3 6 9

    所以,行号和列号别算错了。这样其他代码就可以不变了。

    还需要注意的一点就是就是,如果对矩阵f的每个像素计算的点值要赋值给矩阵g。这个g要在循环外面声明好,而且要固定大小,在parfor循环里面最好也是向量,而非矩阵。计算完成后再用vec2mat函数转换为矩阵,这个函数之后,可能还需要个转置才能得到你需要的结果。

    至于提高的速度来讲,我处理一个680*340的矩阵,用2核提高了2倍,用4核提高了6倍。

    然后就是如何声明你要开启的核(通常来讲就是你的Pc有几个核就声明几个)?

    首先在matlab命令行里输入:matlabpool open local 4

    然后它会提示你一些消息,开启成功后就像以前一样操作就行。不想用了就再输入matlabpool close,关闭并行。

    这些内容也可以写到函数里面去,比如

    function yourFun()

    ....

      matlabpool('open','local',4);   %最后一个参数是你要开启的线程数

        parfor i=1:N

        ...

        end

      matlabpool close

    ....

    end

    如果你的parfor怎么都通不了,或者速度变得更慢了,建议看matlab 帮助中的这一部分,看明白了,自然就有答案了:

  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/naniJser/p/2480974.html
Copyright © 2011-2022 走看看