在大量矩阵上并行化或矢量化所有操作?
-
03-10-2019 - |
题
我有大约5,000个矩阵,这些矩阵具有相同数量的行和不同数量的列(20 x〜200)。必须将这些矩阵与动态编程算法中的所有其他矩阵进行比较。
在 这 问题,我问如何快速进行比较,并给出了涉及2D卷积的出色答案。串行,迭代地应用该方法,
list = who('data_matrix_prefix*')
H = cell(numel(list),numel(list));
for i=1:numel(list)
for j=1:numel(list)
if i ~= j
eval([ 'H{i,j} = compare(' char(list(i)) ',' char(list(j)) ');']);
end
end
end
对于数据的小子集来说是快速的(例如,9个矩阵,9*9-9 = 72个呼叫在〜1 s,870个呼叫中,以〜2.5 s为单位)。
但是,在所有数据上操作需要近2500万个电话。
我还尝试使用Deal()制作完全由数据中的下一个元素组成的单元格数组,因此我可以在一个循环中使用CellFun():
# who(), load() and struct2cell() calls place k data matrices in a 1D cell array called data.
nextData = cell(k,1);
for i=1:k
[nextData{:}] = deal(data{i});
H{:,i} = cellfun(@compare,data,nextData,'UniformOutput',false);
end
不幸的是,这并不是任何更快的速度,因为所有时间都在compare()中。这两个代码示例似乎都不适合并行化。我很难弄清楚如何将变量切成薄片。
比较()完全矢量化;它专门使用矩阵乘法和conv2()(我的印象是所有这些操作(包括cellfun()在内的所有这些操作都应在matlab中多线程?)。
有人看到(明确的)并行化解决方案或更好的问题矢量化吗?
笔记
我意识到我的两个示例效率低下 - 如果计算三角形细胞阵列,则第一个示例的速度是两倍,并且第二个仍在计算自我比较。但是,良好并行化的时间节省更像是16倍(如果我在每个人的机器上安装MATLAB)。
在旁边
还有一个内存问题。我使用几个evals将H的每一列附加到一个文件中,并带有H1,H2等的名称,然后清除H一世. 。不幸的是,节省非常慢...
解决方案
第二个示例可以很容易地切成薄片,以与并行处理工具箱一起使用。该工具箱在最多8个不同的本地处理器中分发代码的迭代。如果要在集群上运行代码,也需要分布式计算工具箱。
%# who(), load() and struct2cell() calls place k data matrices in a 1D cell array called data.
parfor i=1:k-1 %# this will run the loop in parallel with the parallel processing toolbox
%# only make the necessary comparisons
H{i+1:k,i} = cellfun(@compare,data(i+1:k),repmat(data(i),k-i,1),'UniformOutput',false);
%# if the above doesn't work, try this
hSlice = cell(k,1);
hSlice{i+1:k} = cellfun(@compare,data(i+1:k),repmat(data(i),k-i,1),'UniformOutput',false);
H{:,i} = hSlice;
end
其他提示
做
compare(a,b) == compare(b,a)
和
compare(a,a) == 1
如果是这样,请更改您的循环
for i=1:numel(list)
for j=1:numel(list)
...
end
end
到
for i=1:numel(list)
for j= i+1 : numel(list)
...
end
end
并处理对称性和身份案例。这将使您的计算时间减少一半。
如果我正确理解,您必须执行5000^2矩阵比较?也许您应该想到由5000^2个任务组成的问题,而不是尝试并行化比较函数? MATLAB并行计算工具箱支持基于任务的并行性。不幸的是,我在PCT方面的经验是与大型线性代数类型问题的并行化,所以我真的不能告诉您更多的东西。该文档无疑将为您提供更多帮助。