Compression

今回はROSに関するファイル圧縮作業を高速化するための並列処理について紹介する.

概要


自律移動ロボットなどでよく使用されるROSに関し,センサデータなどを記録するrosbagファイルのサイズが非圧縮だと結構膨大なサイズになることが多い. そのため,ディスクの空き容量を増やすために定期的にbagファイルを圧縮する作業が生じると思うが,それらの作業を並列処理で高速圧縮するのが今回のテーマである.

環境


  • Ubuntu 18.04 LTS ( OS )
  • ROS ( melodic )

なお,rosbagファイルはすでに存在する前提で説明する.

逐次処理による圧縮


rosbagファイルを圧縮する際,救いのないほどに何も考えず作業する場合には以下のように1ファイルずつ圧縮すると思う.

rosbag compress -j <bagファイル1>
rosbag compress -j <bagファイル2>
...

これだと,いちいちbagファイルの圧縮が完了したかを確認する必要があり,とっても面倒である. そこで,少し頭を働かせると以下のコマンドになるかと思う.

rosbag compress -j *.bag

ワイルドカードを使用する.これでいちいち確認する必要もない. しかしながらこれはとてももったいない. というのも,これらのやり方は結局逐次処理(一つずつ順番に処理)だからだ. CPUがマルチコアである場合には(ほぼマルチコアだと思うが) このやり方だと,コア数に対して働いているのは常に1コアだけという, 大変もったいないことをしているのである.

htopコマンドで確認すると1コアしか働いていないのが見て取れる.

Sequential

並列処理による圧縮

さて,CPUコアを余すことなく使用するために,そう,並列処理をする. そのためのコマンドは例えば以下の通りである.

# カレントディレクトリ以下のbagファイルをすべて検索しコア数で並列処理をして圧縮する
find ./ -type f -name "*.bag" | xargs -P<コア数> -n1 rosbag compress

htopコマンドで確認すると複数コアが働いていることが分かる(図は2つのrosbagファイルを並列処理で圧縮している時の様子.並列処理は4で指定しているが,ファイルが2つのため2コアのみ働いている)

Parallel

ちなみにCPUのコア数は以下のコマンドでも確認が可能である.

lscpu | grep "^CPU(s):" | awk '{ print $NF}'

どのくらい時短になるのか

さて,並列処理をするとどの程度時短になるかどうか,という点であるが timeコマンドを使用して測定してみた結果,以下の通りになった.

# 実験に使用したrosbagファイルのサイズ情報
rosbag info bagfile1
--> File Size : 4.2 GB

rosbag info bagfile2
--> File Size : 1.3 GB

# 実験環境のCPUコア数は4
lscpu | grep "^CPU(s):" | awk '{ print $NF}'
--> 4
項目 並列処理しない場合 並列処理する場合 時短率
real 8m5.384s 6m15.588s -22%
user 8m1.689s 8m8.660s +1.4%
sys 0m1.984s 0m2.242s +13%

実際に要した時間(real)を見ると,並列処理した時の方が短くなっていることが分かる. ちなみにuserの値はコア数ごとに要した時間を単純に合算しているためrealよりも大きな値となっている.

最後に


時は金成りなので,定期的にリソース状態を監視し本来のパフォーマンスを引き出すことを意識すると良い. せっかくたくさんコアあるのに,暇させるナカレ.

参考URL