matlab - 加载大量数据时如何并行化
问题描述
我一直在努力加快我的 MATLAB 代码的速度,该代码将许多大型数据文件加载到自定义类对象中。我的两个类是 aDataGroup
和 a DataObj
,每个类都DataObj
加载一个独立的 .mat 数据文件,并DataGroup
包含一个数组,DataObj
以便能够访问分布在多个文件中的信息。我们以这种方式分发它是因为每个文件都包含一个具有一组完全不同的字段的结构,因此没有一种很好的方式将它们编译在一起。由于 .mat 文件是一种压缩格式,我相信大部分load
时间实际上是用于解压缩,而不是 HDD 读取。
下面是我试图加速的代码的基本版本。我的问题是这parfor
并没有帮助,实际上使事情变得更糟,因为将大型 rawData 广播回客户端所需的大量开销。我知道开销是原因,因为我不小心saveobj
设置了过载obj.rawData=[];
,这显着提高了速度。和属性设置正确name
,ID
所以我知道数据正在加载。
saveObj 重载很重要,因为 MATLAB 在工作人员之间(并且可能返回客户端)广播变量的方式是“保存”它们,然后将它们“加载”到目的地。由于我有一个自定义类,如果我重载 saveObj 它将在被发送回客户端之前被调用。我还尝试过重载loadobj
以第二次重新加载数据。这保留了信息,但速度比序列化稍差。
这是我在一个小数据集上的计时结果。不同的parfor
方法指示saveobj
和loadobj
重载是启用还是注释掉。
模式 | 时间 |
---|---|
for 环形 |
16 秒 |
parfor 和saveobj (loadobj 数据加载两次) |
18 秒 |
parfor 与saveobj (数据丢失) |
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
解决方案
推荐阅读
- c# - 如果客户端被禁用,则请求拒绝 OpenIdConnect 的事件
- ios - Visual Studio Mac xamarin ios 故事书不适用于 XCode 12
- javascript - 扩展到父级时如何使字体大小变小
- javascript - 用于检查 html5 中素数的 Web Worker 用法
- redis - Gitlab CI中配置Redis主从架构(跨服务通信)
- pandas - 如何在 Pyplot 中禁用 x_axis 标签?
- ipc - DPDK 实例可以在不同容器中的 2 个 linux 应用程序之间共享吗?
- laravel-7 - 大炮添加外键
- java - 使用 AR 计算设备位置
- javascript - 如何使用 React-Bootstrap 根据项目计数创建带有拼接的轮播项目