首页 > 解决方案 > 加载大量数据时如何并行化

问题描述

我一直在努力加快我的 MATLAB 代码的速度,该代码将许多大型数据文件加载到自定义类对象中。我的两个类是 aDataGroup和 a DataObj,每个类都DataObj加载一个独立的 .mat 数据文件,并DataGroup包含一个数组,DataObj以便能够访问分布在多个文件中的信息。我们以这种方式分发它是因为每个文件都包含一个具有一组完全不同的字段的结构,因此没有一种很好的方式将它们编译在一起。由于 .mat 文件是一种压缩格式,我相信大部分load时间实际上是用于解压缩,而不是 HDD 读取。

下面是我试图加速的代码的基本版本。我的问题是这parfor并没有帮助,实际上使事情变得更糟,因为将大型 rawData 广播回客户端所需的大量开销。我知道开销是原因,因为我不小心saveobj设置了过载obj.rawData=[];,这显着提高了速度。和属性设置正确nameID所以我知道数据正在加载。

saveObj 重载很重要,因为 MATLAB 在工作人员之间(并且可能返回客户端)广播变量的方式是“保存”它们,然后将它们“加载”到目的地。由于我有一个自定义类,如果我重载 saveObj 它将在被发送回客户端之前被调用。我还尝试过重载loadobj以第二次重新加载数据。这保留了信息,但速度比序列化稍差。

这是我在一个小数据集上的计时结果。不同的parfor方法指示saveobjloadobj重载是启用还是注释掉。

模式 时间
for环形 16 秒
parforsaveobjloadobj数据加载两次) 18 秒
parforsaveobj(数据丢失) 7 秒
parfor没有过载 160 秒

有没有更好的方法来并行化它以使事情运行得更快?我考虑过DataObj先加载几个 key ,然后在后台加载其余的,也在后台更新DataGroup.dataSet属性,但不知道该怎么做。我尝试使用parfeval但不知道如何让工作人员更新客户端上的对象。

运行脚本

% Data files are all .mat containing a single structure with many different fields
% The fieldnames are different for every data file
% Data files can range from a couple kB to over 1GB
filenames = {'file01.mat','file02.mat',...,'file100.mat'};
tic; allData = DataGroup(filenames); toc

数据组.m

classdef DataGroup < handle

properties
    dataSet
end

methods
function obj = DataGroup(filenames)
    dataSet = repmat(DataObj.empty(),1,length(filenames));
    parfor iFile = 1:length(filenames)
        dataSet(iFile) = DataObj(filenames{iFile});
    end
    obj.dataSet = dataSet;
end
end

数据对象

classdef DataGroup < handle

properties
    rawData
    name
    ID
    srcFile
end

methods
function obj = DataObj(filename)
    obj.rawData = load(filename);
    names = fieldnames(obj.rawData)
    obj.name = names{1};
    obj.ID = parse(obj.name); %some basic character parsing
    obj.srcFile = filename;
end

function b = saveobj(obj)
    b = obj;
    b.rawData = [];
end
end

methods (Static)
function obj = loadobj(b)
    obj = DataObj(b.srcFile);
end
end

标签: matlabconstructorparallel-processingdownload

解决方案


推荐阅读