我有大约200个Rds数据集,我在一个管道(多个脚本)中对这些数据集(不同的脚本)执行各种操作。在大多数剧本中,我都是从
for
foreach
. 我的问题是数据集对象的大小不同(x轴的大小以mb为单位):
因此,如果我优化核心号的使用(我办公室有一台12核16gbRAM的机器,家里有一台16核32gbRAM的机器),它会毫无意外地快速通过前90个,但随后更大的文件会聚集在一起,最大限度地提高RAM的总分配(记住,Rds文件是压缩的,所以它们在RAM中比在磁盘上大,但文件大小的变化至少说明了问题所在)。这会导致worker崩溃,通常会留下1到3个内核来运行其余的大文件(使用
.errorhandling = "pass"
方法1:首先循环或列出磁盘上的文件,可能是通过打开&关闭它们,使用
object.size()
为了得到它们在RAM中的大小,从大到小排序,一半切割,倒转后半部分的顺序,并将它们穿插在一起:最小的、最大的、第二小的、第二大的等等。因此,2个工人(或任何偶数的倍数)应该致力于“平均”RAM的使用。但是:worker 1将比堆栈中的任何其他作业更快地完成其作业,然后进入作业3(第二个最小的作业),很可能非常快地完成该作业,然后执行作业4(第二个最大的作业),而worker 2仍处于最大的作业上,这意味着到作业4,此方法使机器同时处理最大的2个RAM对象,与我们想要的相反。
方法2:在RAM中对每个对象按大小排序,从小到大。从对象1开始,迭代添加后续对象的RAM使用情况,直到超过RAM核心总数。
Foreach
方法3:按2对大小排序。跑
所有的核心。这将最大限度地有效地搅动小任务,直到任务变得更大,此时工人将开始崩溃,减少共享RAM的工人数量,从而增加剩余工人继续工作的机会。从概念上讲,这意味着cores-1任务失败,需要重新运行,但是代码很简单,应该可以快速工作。我已经有了检查输出目录的代码,如果任务已经完成,就从作业列表中删除它们,这意味着我可以重新运行这个方法,但是我应该预料到进一步的损失,因此需要重新运行,除非我降低核心数。
任何遇到类似问题的人的想法。干杯!