我正在使用 GNU 並行處理 BAM 文件,以便使用基於 java 的 picard 工具標記重複項。使用並行實用程式的原因是 picard 工具不是多執行緒的,而且資料集非常巨大。所以我在 GNU 並行中使用以下命令:
ls *.bam | sed 's/.bam.*//' | parallel --eta -j 12 "java -jar picard.jar MarkDuplicates I={}.bam O=/bam1/{}.bam M=/bam1/{}_dup_matrices.txt"
期待 由於我的伺服器有 40 個線程和 126 GB RAM,因此我希望上述命令能夠處理當前目錄中存在的所有 bam 文件,同時一次處理 12 個 bam。
實際產量
最後,我只得到 4 或 5 個已處理的 BAM 文件,而當前目錄有大約 15 個 BAM 文件。我還收到內存溢出錯誤(儘管我已經使用命令檢查了內存分配ulimit
,它顯示無限)。
是否可以使用 GNU 並行實用程序,使其自動處理當前目錄中存在的所有文件,而不會出現記憶體問題?
EDIT-1:我在此處新增輸出ulimit -a
:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 514974
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 514974
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
答案1
java
通常保留的記憶體比使用的記憶體多得多。 10 倍並不罕見。因此,如果我們假設picard
實際使用 3 GB,但保留 30 GB,那麼在記憶體耗盡之前只能並行運行 4 個作業 - 除非添加交換空間。
僅僅因為java
保留了內存,並不意味著它曾經觸及過它。
我的建議是增加 1 TB 交換空間。
您也可以要求 Linux 核心過量使用記憶體。但在執行此操作時,我對伺服器意外崩潰的經歷很糟糕,因此我建議不要使用該解決方案。
但是你能使用 zswap。這樣,如果有任何內容要寫入交換區,核心將首先嘗試壓縮它並將其保存在 RAM 中。只有當失敗時,記憶體才會被寫入磁碟。與磁碟上 1 TB(慢速)交換空間結合,此操作非常有效率。