是否可以使用parfor循环更改两个函数?

时间:2017-08-02 04:11:49

标签: matlab function parfor

假设我有两个函数写在不同的脚本上,比如说function1.mfunction2.m两个函数中的两个计算是独立的(有些输入可能是相同的,比如function1(x,y)和{ {1}}例如)。但是,按顺序运行,比如说function2(x,z)可能会非常耗时。我想知道是否可以在ret1 = function1(x,y); ret2 = function2(x,z);循环中运行它:

parfor

是否可以在parfor i = 1:2 ret(i) = run(['function' num2str(i)]); % if i=1,ret(1)=function1 and i=2, ret(2)=function2 end 循环中编写它?

3 个答案:

答案 0 :(得分:3)

你的想法是正确的,但实施是错误的。

Matlab不允许您在run中使用parfor,因为它无法确保它是使用parfor的有效方式(即没有依赖关系)迭代之间)。正确的方法是使用函数(而不是scrips)和if语句在它们之间进行选择:

ret = zeros(2,1);
parfor k = 1:2
    if k==1, ret(k) = f1(x,y);  end
    if k==2, ret(k) = f2(x,z);  end
end

此处f1f2是一些返回标量值的函数(因此它适用于ret(k),并且每个循环实例都调用不同的if声明。

您可以在此处详细了解how to convert scripts to functions

答案 1 :(得分:1)

parfor循环的经验法则是每次迭代必须是独立的。更确切地说,

  

The body of the parfor-loop must be independent. One loop iteration cannot depend on a previous iteration, because the iterations are executed in a nondeterministic order.

这意味着每次迭代必须是一个可以自己执行并产生正确结果的迭代。

因此,如果你有代码,例如,

parfor (i = 1:2)
    function1(iterator,someNumber); 
    function2(iterator,someNumber);
end

申请parfor应该没有问题。

但是,如果你有代码,例如,

persistentValue = 0;
parfor (i = 1:2)
    persistentValue = persistentValue + function1(iterator,someNumber); 
    function2(iterator,persistentValue);
end

它不可用。

答案 2 :(得分:0)

是。这是可能的。

以下是一个例子:

ret = zeros(2,1);
fHandles = {@min, @max};
x = 1:10;        
parfor i=1:2
    ret(i) = fHandles{i}(x);    
end
ret   % show the results.

这是否是个好主意,我不知道。设置并行处理会产生开销,这可能会或可能不会使您感到有价值。

  1. 通常,您计算的迭代次数越多,设置parfor循环所获得的值越多,因为迭代被切片并且非确定性地发送到单独的核心进行处理。所以你现在正在使用2个核心,但如果你有很多功能,这可能会改善一些事情。
  2. 不保证迭代运行的顺序(可能是为一个核心分配了i的值范围,但我们不知道这些值是按顺序还是随机获取),因此您的代码可以不依赖于循环的其他迭代。
  3. 一般来说,MATLAB编辑器非常注重提前解决这些问题。

    修改

    这是对不同函数的可变数量参数的概念证明

    ret = zeros(2,1);
    fHandles = {@min, @max};
    x = 1:10;         % x is a 1x10 vector
    y = rand(20);     % y is a 20x20 matrix
    z = 1;            % z is a scalar value
    fArgs = {{x};
             {y,z}};  %wrap your arguments up in a cell
    parfor i=1:2
        ret(i) = fHandles{i}([fArgs{i}{:}]);  %calls the function with its variable sized arguments here
    end
    ret   % show the output
    

    同样,这只是概念验证。在MATLAB中出现了很大的警告,要求在所有内核中广播 fArgs