link-u / davif

avif decoder, using dav1d directly.
MIT License
41 stars 12 forks source link

タイル分割を指定してもデコードが並列実行できていない? #2

Open k2w4t4h opened 4 years ago

ledyba-z commented 4 years ago

https://github.com/link-u/cavif/issues/8 でファイルの分割はできるようになり、 https://github.com/link-u/davif/commit/dff371cda1dd5fbfa8779a80194338a5300cb577 でマルチスレッドにも対応したんですが、速くなりませんなぁ。

1x1

 % time cmake-build-debug/davif -i ../cavif/hato.1x1.avif -o hato.png
[2020/02/02 17:41:57 INFO ] davif
[2020/02/02 17:41:57 DEBUG] dav1d ver: 0.5.2-5-g481c059
[2020/02/02 17:41:57 INFO ] Decoding: ../cavif/hato.1x1.avif -> hato.png
[2020/02/02 17:42:00 INFO ] Decoded in 3011 [ms]
cmake-build-debug/davif -i ../cavif/hato.1x1.avif -o hato.png  6.73s user 0.04s system 102% cpu 6.571 total

2x2 (--tile-rows 1 --tile-columns 1)

time cmake-build-debug/davif -i ../cavif/hato.2x2.avif -o hato.png --threads 4
[2020/02/02 18:20:04 INFO ] davif
[2020/02/02 18:20:04 DEBUG] dav1d ver: 0.5.2-5-g481c059
[2020/02/02 18:20:04 INFO ] Decoding: ../cavif/hato.2x2.avif -> hato.png
[2020/02/02 18:20:08 INFO ] Decoded in 3084 [ms]
cmake-build-debug/davif -i ../cavif/hato.2x2.avif -o hato.png --threads 4  6.90s user 0.01s system 103% cpu 6.699 total

なんか同じスレッドに仕事投げ続けてないかとか調べてみます。

ledyba-z commented 4 years ago

一応何かしらの処理はしてるみたいなんですが、なんかやたらスレッドが遊んでて、それは単に分割できる仕事がそんなに無いからなのか、それとも何か他に原因があるのか、明日見てみます

image

ledyba-z commented 4 years ago

@k2w4t4h

CDEFとLoop Restorationフィルタだけはメインスレッドで実行されるので、これをまず無効にしてさらに画像のサイズを大きくして(3082x2048)みました:

実験

画像の作り方

サンプル画像に入ってる中では一番解像度が大きいhato.pngでやります。

1x1(分割なし)

cavif -i ../avif-sample-images/hato.png -o hato.1x1.avif --disable-cdef --disable-loop-restoration --tile-rows 0 --tile-columns 0 --crf 18 --show-result

2x2(4つに分割)

cavif -i ../avif-sample-images/hato.png -o hato.2x2.avif --disable-cdef --disable-loop-restoration --tile-rows 1 --tile-columns 1 --crf 18 --show-result

デコードして測定

1x1(分割なし)

1スレッド

davif -i ../cavif/hato.1x1.avif -o hato.1x1.png --threads 1
[2020/02/09 12:57:37 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 12:57:37 INFO ] Decoded in 257 [ms]

4スレッド

davif -i ../cavif/hato.1x1.avif -o hato.1x1.png --threads 4
[2020/02/09 12:58:11 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 12:58:11 INFO ] Decoded in 229 [ms]

--threads 1だと全部メインスレッドでしか行わないのだが、複数個にすると一応デコードとその後の後フィルタ処理(CDEFとLoop Restorationは無効にしているのだが、7.14. Loop filter processだけは切れないので残る)が並列で行われるようになるのですこーし速くなるっぽい。

2x2(分割あり)

1スレッド

davif -i ../cavif/hato.2x2.avif -o hato.2x2.png --threads 1
[2020/02/09 12:56:42 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 12:56:42 INFO ] Decoded in 245 [ms]

4スレッド

davif -i ../cavif/hato.2x2.avif -o hato.2x2.png --threads 4
[2020/02/09 12:57:04 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 12:57:04 INFO ] Decoded in 95 [ms]

2.5倍速ぐらいにはなったのでとりえあず「並列実行されてます!」と言い張ってもよいのではないだろうか。

ledyba-z commented 4 years ago

分割の仕方についてなんですが、特定のy座標の処理が全部終わるまで全スレッドを待ってからフィルタを掛ける処理が入っていたので、たぶん横に4分割するよりは縦に4分割するほうが速そうに見える

ledyba-z commented 4 years ago

間違ってはなさそうだけど、言い切るには10回ぐらい測定して検定でもしないと何とも言えないやつだ…

横4分割

davif -i ../cavif/hato.1x4.avif -o hato.1x4.png --threads 4
[2020/02/09 13:17:05 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 13:17:06 INFO ] Decoded in 96 [ms]

縦4分割

davif -i ../cavif/hato.4x1.avif -o hato.4x1.png --threads 4
[2020/02/09 13:18:43 DEBUG] dav1d ver: 0.5.2-75-g8974c15
[2020/02/09 13:18:43 INFO ] Decoded in 85 [ms]
ledyba-z commented 4 years ago

規格を読む限りCDEFも別スレッドでタイルごとに動かせるような気がしてならないので「なんでしないの?」って聞いてみるのはありかもしれない

ledyba-z commented 4 years ago

聞いた

Why loopfilter + cdef + restoration are not applied in separated tile-threads? (#331) · Issues · VideoLAN / dav1d · GitLab https://code.videolan.org/videolan/dav1d/issues/331