matlab - 向 worker 发送数据

标签 matlab parallel-processing parfor spmd

我正在尝试创建一段并行代码来加速处理一个非常大的(几亿行)数组。为了并行化,我将数据分成 8 份(我的核心数),并尝试向每个工作人员发送 1 份。然而,看看我的 RAM 使用情况,似乎每件作品都发送给了每个工作人员,有效地将我的 RAM 使用量乘以 8。一个最小的工作示例:

A = 1:16;
for ii = 1:8
    data{ii} = A(2*ii-1:2*ii);
end

现在,当我使用 parfor 将此数据发送给工作人员时,它似乎发送了完整的单元格,而不仅仅是所需的部分:

output = cell(1,8);
parfor ii = 1:8
    output{ii} = data{ii};
end

我实际上在 parfor 循环中使用了一些函数,但这说明了这种情况。 MATLAB 是否真的将完整的单元格 data 发送给每个 worker,如果是这样,如何让它只发送所需的部分?

最佳答案

根据我的个人经验,我发现使用 parfeval 在内存使用方面比 parfor 更好。此外,您的问题似乎更容易破解,因此您可以使用 parfeval 向 MATLAB worker 提交更多较小的作业。

假设您有 workerCnt 个 MATLAB worker,您将为其处理 jobCnt 个作业。设 data 是一个大小为 jobCnt x 1 的元胞数组,它的每个元素对应于函数 getOutput 的一个数据输入,该函数执行分析在数据上。然后将结果存储在大小为 jobCnt x 1 的元胞数组 output 中。

在下面的代码中,作业在第一个 for 循环中分配,结果在第二个 while 循环中检索。 bool 变量 doneJobs 指示哪个作业已完成。

poolObj = parpool(workerCnt);
jobCnt = length(data); % number of jobs
output = cell(jobCnt,1);
for jobNo = 1:jobCnt
    future(jobNo) = parfeval(poolObj,@getOutput,...
        nargout('getOutput'),data{jobNo});
end
doneJobs = false(jobCnt,1);
while ~all(doneJobs)
    [idx,result] = fetchnext(future);
    output{idx} = result;
    doneJobs(idx) = true;
end

此外,如果您想节省更多内存,可以进一步采用这种方法。你可以做的是,在获取完成的工作的结果后,你可以删除 future 的相应成员。原因是这个对象存储了 getOutput 函数的所有输入和输出数据,这可能会很大。但是您需要小心,因为删除 future 的成员会导致索引偏移。

下面是我为这只海豚写的代码。

poolObj = parpool(workerCnt);
jobCnt = length(data); % number of jobs
output = cell(jobCnt,1);
for jobNo = 1:jobCnt
    future(jobNo) = parfeval(poolObj,@getOutput,...
        nargout('getOutput'),data{jobNo});
end
doneJobs = false(jobCnt,1);
while ~all(doneJobs)
    [idx,result] = fetchnext(future);
    furure(idx) = []; % remove the done future object
    oldIdx = 0;
    % find the index offset and correct index accordingly
    while oldIdx ~= idx
        doneJobsInIdxRange = sum(doneJobs((oldIdx + 1):idx));
        oldIdx = idx
        idx = idx + doneJobsInIdxRange;
    end
    output{idx} = result;
    doneJobs(idx) = true;
end

关于matlab - 向 worker 发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32095552/

相关文章:

c - 单线程模式下并行合并非常慢

matlab - 并行化程序

matlab - 为什么用于线性回归的简单 MATLAB 梯度下降不起作用

python - 如何生成波特图矩阵?

Matlabpool 开 worker 很慢

c# - 如何在某些任务非常昂贵的任务中负载平衡并行性?

parfor 内存不足错误 : kill the slave, 不是 master

matlab - 在外部 for 中使用 parfor 的两个循环错误

matlab - Matlab 中 'end' 的语义是什么?

matlab - 计算矩阵中每一行的范数