【发布时间】:2021-08-25 08:47:45
【问题描述】:
我有一个在高性能集群上并行运行的密集模拟任务。
每个线程 (~3000) 都使用 R 脚本编写模拟输出,并使用 data.table 包的 fwrite 函数。
我们的 IT 人员告诉我要使用锁。所以我使用flock包在所有线程都写入文件时锁定文件。
但这创造了一个新的瓶颈。大多数情况下,进程等到可以写入为止。现在我想知道如何评估锁是否真的有必要?对我来说,所有作业超过 90% 的处理时间都花在等待锁上,这似乎很奇怪。
当我只使用fwrite 函数和参数append = T 将结果附加到csv 时,谁能告诉我是否真的需要使用锁?
编辑: 我已经尝试过编写单个文件并在所有工作完成后以各种方式合并它们。但是合并的时间也太长,无法接受。
将所有模拟结果写入一个文件而不加锁似乎仍然是最好的方法。这工作得非常快,并且在没有锁定的情况下进行少量模拟时我没有发现错误。
在没有锁的情况下编写会导致一些在运行数百万次模拟后不会被注意到的问题吗?
【问题讨论】:
-
这些线程是否写入同一个文件?你不能让每个进程写入不同的文件吗?那么锁应该是不必要的。这些文件可以在后处理步骤中合并。
-
是的,他们写入一个文件。我已经尝试过您提出的选项。但是读取和合并总计大于 100 mb 的约 100k 文件显然也需要大量时间。所以这个选项在处理时间方面并没有真正的优势。
-
你是如何阅读和合并它们的?该步骤应该比任何涉及需要锁定的共享文件的方法快得多。当然,最好的方法是使用数据库。
-
我使用“>>”将文件附加到集群上,我还尝试了一些 R 函数。您对使用数据库有何建议?我考虑了一个数据库,但认为仅将行写入文件可能会再次产生过多的开销。
-
好吧,我会从每个线程保存到一个单独的文件中,
lapply(..., fread)覆盖文件并使用,例如rbindlist。或者使用其他软件合并文件(sed、awk、...)。
标签: r multithreading parallel-processing data.table hpc