-
-
Notifications
You must be signed in to change notification settings - Fork 702
Move tiff JPEG compression outside the lock and thread it #3679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thank you @jcupitt for starting this PR. If I understand correctly, it still running on single thread even after move it inside libvips? I failed to compile this version on ubuntu. There may be some issues compiling jpeg2vips. Looking forward to test it. |
TODO:
|
You're right, it still needs a threadpool to write each line of tiles. I'll put that in next. |
I added threaded write (as well as compression by libvips). Git master libvips:
This PR:
So about 50% faster on this PC, nice! |
That's pretty impressive. I am waiting for tomorrow to do some testing. Hope I can build it for windows successfully first. My test will be using a very large image where the old version took almost 1h to finish. |
This is the largest test image I have to hand:
|
Ah jp2k compression sees more of a speedup. Before:
After:
|
That again a very big improvement. So 70 % faster in case of jp2k and 35% faster in jpeg. Silly question : what's the advantage of using jp2k over jpeg in tiff compression? The jpeg tiles are very small and in term of their sizes, they are probably smaller and faster to load. |
jp2k doesn't really have any advantages imo, it's just there for compatibility with some deranged software that still uses it. |
by copying the TIFFTAG_JPEGTABLES tag
Ah I found another speedup: we can copy the Git master:
This PR:
More than 2x faster now. |
Is this TIFFTAG_JPEGTABLES only optimized for Q=70 the default value? Tifftag_jpegtables |
It's created for each Q value. |
OK, all done, I think. |
That was very fast for >50% improvement. Now to test it, do I need to compile this branch in mxe for windows? |
No idea, probably! I think it should work. |
I just updated the $ ./build.sh --ref tiffsave-threaded-jpeg |
Thank you. Build successfully. Now I will test it using my large images. update: Thank you @jcupitt for the excellent results; I did not believe it :)
file_size= 6.16GB
file_size = 7.67GB edit: Thank you @jcupitt and @kleisauke for the improvement. |
It looks like this PR would cause non-deterministic output. See for example this test script: vips copy CMU-1.svs[rgb] x.tif[compression=jpeg,tile,pyramid]
expected_sha256=$(sha256sum "x.tif" | awk '{ print $1 }')
for run in {1..5}; do
vips copy CMU-1.svs[rgb] x.tif[compression=jpeg,tile,pyramid]
echo "$expected_sha256 x.tif" | sha256sum --check
done Git master: $ ./check-deterministic.sh
x.tif: OK
x.tif: OK
x.tif: OK
x.tif: OK
x.tif: OK This PR: $ ./check-deterministic.sh
x.tif: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
x.tif: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
x.tif: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
x.tif: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
x.tif: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match |
Is this test will verify the output hash? The size of the output is changing from run to run. |
Certainly -- it's writing the tiles across a row in parallel, so the tile order is set by which thread finishes first. We could buffer all the compressed tiles in the row, then sort and write them sequentially, but it would obviously raise memory use. |
Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
Co-authored-by: Kleis Auke Wolthuizen <github@kleisauke.nl>
Thinking about it, you're right, non-deterministic output is pretty bad. I'll add gather-sort-write. Hopefully memory use won't increase too much. |
It should be sorted now.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Test it and it works well on windows. Thank you. |
Great! Thanks for testing @euzada |
At the moment, libvips uses libtiff to write JPEG compressed tiles. Since compression is inside libtiff, it has to be single-threaded.
This PR moves JPEG compression into libvips and uses a threadpool to write JPEG and JP2K compressed tiles in parallel.
git master:
This PR: