Cerium による並列処理向け I/O の実装 |
Masataka Kohagura,Shinji Kono,
|
ファイルを読み込んで計算を行うようなアプリケーションは、I/O の速度を無視することができない。 ファイルを全て読み込んでから並列計算をすると、読み込んでいる時間がオーバーヘッドとなってしまう。
本研究室では、並列プログラミングフレームワーク Cerium を使用することによって並列計算を可能にしているが、Cerium で I/O と並列計算を同時に走らせるにはどのように実装すればいいか考慮した。
上記 2点を実装して、I/O と並列計算が同時に実行し、なおかつ I/O の処理を乱されないようにすることによって、全体のパフォーマンスを上げたい。
I/O の読み込みと並列計算の方法は以下の 3 つの方法を試みた。
-> 本研究では並列計算を Word Count で実装を行った。
mmap を使用せずに、read を独立したスレッドで実行させる。そして、読み込んだ部分に対して Word Count を並列に起動する。
I/O は、ディスクからの読み込む時間がかかる。
-> I/O をどのように実装したら、並列処理とI/Oが干渉をなくして全体のパフォーマンスを上げれるか??
そこで本研究では、
以上3点を行った。
Cerium Task Manager:
CellおよびLinux、 Mac OS X 上で動く並列プログラミングフレームワーク
|
User が Word Count などの Task を生成して、それらを GPU や CPU などに計算させるように User 自身で設定することができる。
ファイルを読みながら、Word Count や grep などを 並列実行したい。
計算よりも読み込みを優先しなければならない。読み込みで待ちが入ってしまうので、IO Thread を追加。
読み込みながら並列計算を実行する方法を、Blocked Read と名付けた。
実験環境
% sudo purgeを実行して繰り返し、測定を行っている。
全ての実験のfile size は 1GB であり、表内の数値の単位は全て秒である。
Blocked read Task 1つ当たりの読み込み量 : 16kbyte * 48
read mode \ CPU num | CPU 1 | CPU 4 | CPU 8 | CPU 12 | GPU(CUDA) | |
mmap | 15.353 | 11.287 | 11.707 | 11.137 | 103.410 |
|
read | 16.846 | 11.730 | 11.487 | 11.437 | 106.050 |
|
Blocked Read(SPE_ANY) | 13.297 | 11.984 | 10.887 | 11.146 | 94.626 |
|
Blocked Read(IO_0) | 11.503 | 11.437 | 11.365 | 11.412 | 94.496 |
ファイルがキャッシュに入った時の実行速度は以下のようになった。
read mode \ CPU num | CPU 12 | GPU | |
mmap | 0.854 |
94.479 |
|
read | 1.487 |
94.614 |
|
Blocked Read(SPE_ANY) | 0.847 |
93.920 |
|
Blocked Read(IO_0) | 0.866 |
93.912 |
filesize : 1GB
Blocked read Task 1つ当たりの読み込み量 : 128 kbyte * 48
read mode \ CPU num | CPU 1 | CPU 4 | CPU 8 | CPU 12 | |
mmap | 20.179 | 22.861 | 22.789 | 22.713 | |
read | 21.351 | 15.737 | 14.785 | 12.520 | |
Blocked Read(SPE_ANY) | 18.531 | 15.646 | 15.287 | 14.028 | |
Blocked Read(IO_0) | 13.930 | 14.634 | 14.774 | 10.295 |
実験1との比較
Blocked read Task 1つ当たりの読み込み量 : 16 kbyte * 48
read mode \ CPU num | CPU 1 | CPU 4 | CPU 8 | CPU 12 | |
mmap | 15.353 | 11.287 | 11.707 | 11.137 | |
read | 16.846 | 11.730 | 11.487 | 11.437 | |
Blocked Read(SPE_ANY) | 13.297 | 11.984 | 10.887 | 11.146 | |
Blocked Read(IO_0) | 11.503 | 11.437 | 11.365 | 11.412 |
word count task 1つ当たりの処理量を 4kbyte ~ 256kbyte で変化させてみた。
CPU 12 で全て測定している。
read mode \ Blocled Read size | 4k * 48 | 8k * 48 | 16k * 48 | 32k * 48 | 64k * 48 | 128k * 48 | 256k * 48 | |
mmap | 11.867 |
10.570 |
11.803 |
14.915 |
16.626 |
16.923 |
18.474 |
|
read | 12.020 |
11.585 |
11.729 |
11.661 |
12.497 |
11.347 |
11.658 |
|
Blocked Read(SPE_ANY) | 11.508 |
15.932 |
11.407 |
12.816 |
12.454 |
12.891 |
11.962 |
|
Blocked Read(IO_0) | 11.342 |
12.242 |
11.636 |
12.331 |
10.870 |
11.295 |
11.723 |
Blocked read Task 1つ当たりの読み込み量 : 16 kbyte * 48
OS : Mac OS 10.9.2
madvise flag | time(s) | |
MADV_NORMAL(default) | 11.841 |
|
MADV_RANDOM | 42.891 |
|
MADV_SEQENTIAL | 38.935 |
|
MADV_WILLNEED | 10.916 |
|
MADV_DONTNEED | 17.506 |
|
MADV_FREE | 16.863 |
ファイルをキャッシュから追い出すために、以下のコマンドを実行した。
% sysctl -w vm.drop_caches=3
Blocked read Task 1つ当たりの読み込み量 : 16 kbyte * 48
read mode \ CPU num | CPU 1 | CPU 2 | CPU 3 | CPU 4 | CPU 8 | |
mmap | 6.852 |
6.765 |
7.632 |
12.504 |
7.649 |
|
read | 10.545 |
8.699 |
8.667 |
8.152 |
7.607 |
|
Blocked Read(SPE_ANY) | 8.686 |
10.606 |
12.995 |
11.799 |
14.723 |
|
Blocked Read(IO_0) | 6.751 |
6.800 |
7.311 |
7.016 |
6.755 |
実験1の測定結果(Mac OS X)
read mode \ CPU num | CPU 1 | CPU 4 | CPU 8 | CPU 12 | |
mmap | 15.353 | 11.287 | 11.707 | 11.137 | |
read | 16.846 | 11.730 | 11.487 | 11.437 | |
Blocked Read(SPE_ANY) | 13.297 | 11.984 | 10.887 | 11.146 | |
Blocked Read(IO_0) | 11.503 | 11.437 | 11.365 | 11.412 |
mmap での実行時は、Blocked Read size を小さくしたほうが速度が向上した。これは、まとめと読み込むサイズが小さくなればなるほど、sequential access に近い動作になるからであると考えられる。
I/O の読み込みと並列計算を分離して、同時に処理させたほうが、全体的に安定した速度がでるが、mmapだと一度に読み込む大きさが小さければ速い。
mmapは読み込みの大きさによって全体の速度が変わってしまうが、どんな大きさでも安定した速度で改良する余地があると思われる。