【发布时间】:2013-11-19 14:07:58
【问题描述】:
我正在为来自 PDE 的特定离散化(具有已知的稀疏结构)的非常大的稀疏矩阵进行自适应矩阵向量乘法的 MATLAB 实现。
经过大量预处理后,我最终得到了许多不同的块(例如,大于 200),我想为其计算选定的条目。
其中一个预处理步骤是确定我要计算的每个块的(数量)条目,这让我几乎完美地衡量了每个块将花费的时间量(对于所有意图和目的,求积每个条目的努力都是相同的)。
感谢https://stackoverflow.com/a/9938666/2965879,我能够通过以相反的顺序对块进行排序来利用这一点,从而促使 MATLAB 先从最大的块开始。
但是,每个块的条目数差异很大,以至于直接运行 parfor 会受到条目数最多的块的严重限制,即使它们被反向输入循环。
我的解决方案是串行执行最大的块(但在条目级别上并行化!),这很好,只要每个迭代的开销无关紧要,分别。块不会变得太小。然后我用 parfor 完成其余的块。理想情况下,我会让 MATLAB 决定如何处理这个问题,但是由于嵌套的 parfor 循环失去了并行性,这不起作用。此外,将两个循环打包成一个(几乎)是不可能的。
我现在的问题是如何最好地确定串行和并行机制之间的界限,同时考虑到我所掌握的关于条目数量的信息(对于不同的问题,有序条目的曲线形状可能会有所不同),以及我可用的工人数量。
到目前为止,我一直在与标准 PCT 许可下可用的 12 名工作人员一起工作,但是自从我现在开始在集群上工作,确定这个截止值变得越来越重要(因为对于许多内核来说与并行循环相比,串行循环的开销变得越来越昂贵,但类似地,拥有支撑其余部分的块的成本更高)。
对于 12 个内核(分别是我正在使用的计算服务器的配置),我已经找到了一个合理的参数,即每个工作人员 100 个条目作为截止值,但是当内核数量时,这并不适用相对于块的数量不再小了(例如 64 对 200)。
我尝试减少具有不同功率(例如 1/2、3/4)的内核数量,但这也无法始终如一地工作。接下来,我尝试将块分组并确定当条目大于每批平均值时的截止值,resp。他们离结束的批次数:
logical_sml = true(1,num_core); i = 0;
while all(logical_sml)
i = i+1;
m = mean(num_entr_asc(1:min(i*num_core,end))); % "asc" ~ ascending order
logical_sml = num_entr_asc(i*num_core+(1:num_core)) < i^(3/4)*m;
% if the small blocks were parallelised perfectly, i.e. all
% cores take the same time, the time would be proportional to
% i*m. To try to discount the different sizes (and imperfect
% parallelisation), we only scale with a power of i less than
% one to not end up with a few blocks which hold up the rest
end
num_block_big = num_block - (i+1)*num_core + sum(~logical_sml);
(注意:此代码不适用于长度不是num_core 的倍数的向量num_entr_asc,但为了便于阅读,我决定省略min(...,end) 结构。)
我还省略了 < max(...,...) 以结合这两个条件(即与每个工人的最低条目一起),这是必要的,这样就不会太早发现截止。我也考虑过以某种方式使用方差,但到目前为止,所有尝试都不尽如人意。
如果有人知道如何解决这个问题,我将不胜感激。
感谢您阅读这个很长的问题,
最好的问候,
阿克塞尔
附言。由于我的“亲爱的 stackoverflow”似乎被过滤了,让我感谢我已经在这里找到了我的问题的解决方案。
【问题讨论】:
-
正如他们所说,最好的感谢就是支持答案(我相信你在那些场合已经这样做了):-)
-
不是一个答案,但你的很多问题都可以归结为>我现在的问题是关于如何最好地确定串行和并行机制之间的截止[循环]。
-
@ijkilchenko:你说的完全正确,也许我把“具体”的建议看得太字面意思了...... ;-)
标签: matlab parallel-processing load-balancing parfor