Gnu-Parallel
GNU 並行時間戳輸出
我不是 perl 程序員,我認為使用 –tagstring 會很容易,但基本上我想從 Parallel 單獨為每個作業的每一行輸出加時間戳。比如,如果正確替換“STUFF”,輸出可能看起來像,假設毫秒解析度(儘管納秒解析度也不錯):
$ seq 8 | parallel --tags 'sequence {} {=STUFF=}' -j2 'sleep=$((1 + RANDOM % 2)); echo sleeping $sleep; sleep $sleep; echo done; echo $sleep {#} {%} {}' sequence 1 0.001 sleeping 1 sequence 1 1.001 done sequence 1 1.002 1 1 1 1 sequence 2 0.001 sleeping 2 sequence 2 2.001 done sequence 2 2.002 2 2 2 2 sequence 3 0.001 sleeping 2 sequence 3 2.001 done sequence 3 2.002 2 3 1 3 sequence 5 0.001 sleeping 1 sequence 5 1.001 done sequence 5 1.002 1 5 1 5 sequence 4 0.001 sleeping 2 sequence 4 2.001 done sequence 4 2.002 2 4 2 4 sequence 6 0.001 sleeping 1 sequence 6 1.001 done sequence 6 1.002 1 6 1 6 sequence 7 0.001 sleeping 2 sequence 7 2.001 done sequence 7 2.002 2 7 2 7 sequence 8 0.001 sleeping 2 sequence 8 2.001 done sequence 8 2.002 2 8 1 8
你會欺騙性地認為這很容易,我不能為此責怪你。
但是,正常輸出是不可能的。
這是因為 tagstring 只計算了兩次,並且只在作業完成後才添加。
GNU 並行執行:
job1 > tmpout1 2> tmperr1 job2 > tmpout2 2> tmperr2 job3 > tmpout3 2> tmperr3
(這當然不是 100% 正確,但已經足夠接近了)。
工作完成後,GNU Parallel 會以
tmp*
大塊的形式讀取文件,添加--tagstring
並輸出工作。這裡的重要部分是:在執行時不進行標記。並且
--tagstring
只計算兩次:作業開始之前和作業完成之後(這是將添加的最終結果)。之所以選擇此設計,是因為計算標記字元串會消耗 CPU,並且如果您的輸出是 3600000 行,那麼即使是 1 毫秒/行的延遲也將是 1 小時(!)的等待。
但是,有一個例外:
--line-buffer
.
--line-buffer
確實為每一行輸出計算標籤字元串。之所以選擇這種設計,是因為--line-buffer
已經佔用了更多的 CPU 時間(必須從每個正在執行的作業中輪詢新數據並且不能只處理大塊數據)。所以這有效:
$ seq 8 | parallel --lb --tagstring 'sequence {} {= $start{$job}||=::now(); $_=sprintf"%06.3f",::now()-$start{$job} =}' -j2 'sleep 1; echo Begin {}; sleep 0.{}; echo End {}'|sort sequence 1 01.027 Begin 1 sequence 1 01.116 End 1 sequence 2 01.024 Begin 2 sequence 2 01.216 End 2 sequence 3 01.098 Begin 3 sequence 3 01.312 End 3 sequence 4 01.049 Begin 4 sequence 4 01.411 End 4 sequence 5 01.031 Begin 5 sequence 5 01.509 End 5 sequence 6 01.039 Begin 6 sequence 6 01.613 End 6 sequence 7 01.048 Begin 7 sequence 7 01.711 End 7 sequence 8 01.071 Begin 8 sequence 8 01.811 End 8