Parallel processing 如何将多个参数以倍频程传递给并行操作?

Parallel processing 如何将多个参数以倍频程传递给并行操作?,parallel-processing,octave,Parallel Processing,Octave,我编写了一个函数,作用于输入矩阵中的每一列组合。它使用多个for循环,速度非常慢,因此我尝试将其并行化,以便在我的计算机上使用最大数量的线程 我很难找到正确的语法来设置它。我正在使用倍频程中的并行包,并尝试了几种方法来设置调用。以下是其中两个,简化形式,以及我认为有效的非并行版本: function A = parallelExample(M) pkg load parallel; # Get total count of columns ct = columns(M); # Generat

我编写了一个函数,作用于输入矩阵中的每一列组合。它使用多个for循环,速度非常慢,因此我尝试将其并行化,以便在我的计算机上使用最大数量的线程

我很难找到正确的语法来设置它。我正在使用倍频程中的并行包,并尝试了几种方法来设置调用。以下是其中两个,简化形式,以及我认为有效的非并行版本:

function A = parallelExample(M)
pkg load parallel;

# Get total count of columns
ct = columns(M);

# Generate column pairs
I = nchoosek([1:ct],2);
ops = rows(I);
slice = ones(1, ops);
Ic = mat2cell(I, slice, 2);

##  # Non-parallel
##  A = zeros(1, ops);
##  for i = 1:ops
##      A(i) = cmbtest(Ic{i}, M);
##  endfor

# Parallelized call v1
A = parcellfun(nproc, @cmbtest, Ic, {M});

## # Parallelized call v2
## afun = @(x) cmbtest(x, M);
## A = parcellfun(nproc, afun, Ic);

endfunction

# function to apply
function P = cmbtest(indices, matrix)

colset = matrix(:,indices);
product = colset(:,1) .* colset(:,2);
P = sum(product);

endfunction
对于这两个示例,我生成了两列的每一个组合,并将这些对转换为一个单元数组,parcellfun函数应该将其拆分。在第一个示例中,我尝试将输入矩阵M转换为1x1单元数组,以便它以相同的形式到达每个并行实例。我得到错误“C必须是单元格数组”,但这必须是parcellfun函数的内部。在第二部分中,我尝试定义一个包含矩阵的匿名函数。我在这里得到的错误指定“cmbtest”未定义

(当然,我尝试应用的实际函数远比这里的测试复杂)

我尝试过的其他事情:

  • 将M放入全局变量中,这样就不需要传递它。似乎不可能在函数文件中放入全局变量,尽管我可能只是有语法问题
  • 使cmbtest成为嵌套函数,以便它可以访问M(parcellfun不支持该功能)

我现在没有主意了,需要你帮我弄清楚如何让它发挥作用。

将我上面的评论转化为答案

在执行并行操作时,将每个并行工作线程看作是独立的倍频程实例是很有用的,这些倍频程实例需要适当地访问所有函数和变量,以便执行其独立的工作

因此,在从主功能调用
parcellfun
时,不要依赖子功能,因为如果工作人员无法直接访问引擎盖下的子功能,这可能会导致错误


在这种情况下,将子函数分离到它自己的文件中解决了问题。

您的第一个示例按预期对我起作用,返回了正确的输出。这个例子在你的机器上不起作用吗?它不起作用。我得到“错误:mat2cell:维度1(1!=2)上的不匹配”10次,但没有显示错误发生的位置。我的假设是这意味着它发生在parcellfun的某个地方。我测试了该示例的非并行版本,以验证我添加到上述描述中的抛出测试函数中没有明显的问题。您是否更改了上面发布的语法以使其工作?这取决于。从您的示例中不清楚您的代码是如何构造的,或者您的代码是如何运行的。我怀疑您的cmbtest函数可能不在它自己的文件中,而是作为子函数声明在同一个文件中?如果是这样,这可能会有问题,因为并行工作程序(您可以将其视为全新的、干净的状态八度实例)可能无法访问此函数。还有,我不知道你用什么来称呼它。如果我将parallelExample.m和cmbtest.m分离到它们自己的文件定义中,并以m=magic(5)为例运行,那么我将得到预期的结果。此外,理论上,对于等效参数,parcellfun应该给出与cellfun完全相同的结果。如果要测试语法是否正确,请不要将其与for循环进行比较,而是将其与等效的普通
cellfun
调用进行比较。我在实际实现中找到了问题。在多线程和避免慢for循环之间,我看到在我的12线程计算机上性能提高了约23倍@TasosPapastylianou,如果你想把你的建议写下来作为答案,我可以把它设置为正确的——当调用的函数在一个单独的文件中时,我的“并行调用v1”似乎可以正常工作。