OpenImageIO/oiio — pull request #557 by lgritz (2013-04-02 22:10:01+00:00)
Title: Improve resize speed by 10x

1. Instrument oiiotool so that "--runstats" prints runtime statistics including time spent broken down by function (how much is "fit", how much is reading files, how much is "over", etc.). Makes it easier to zero in on where the time goes.

2. Minor refactor of IBA::resize() to use be fully type-specialized and use IB::Iterator rather than setpixel(). (Speedup is very minor but it feels better to me, also lifts the restrictions on input and output types.)

3. Noticed that IBA::resize() was making the filter sampling region too big -- used both a ceil() and a "+1" to pad the filter area, that was overkill. Just the ceil is enough to ensure that we iterate over all the pixels covering the filter. (Speeds up by about 20%.)

4. Refactor IBA::resize to use threads! It didn't even try to parallelize before. This is a big help, but maxes out at about 2-3x speedup because...

5. I further noticed that for ImageCached-backed ImageBuf's (as oiiotool uses), once a few threads are all iterating over the same image simultaneously, they end up locking against each other for control of the single file handle of the open file. So for oiiotool, I "force read" the image if it's not too large, rather than always relying on the ImageCache. Once the read is complete, the threads (each of which are doing the resize work for a portion of the output) don't lock against each other at all, so we have almost perfect linear speedup with threads.

Bottom line: all these changes together speed up an "oiiotool --fit" of a 1024x655 (resized at high quality into 720x547) from around 2.5s to < 0.25s (at least 10x) on my workstation with 12 cores.

There's nothing like production pointing out that something is too slow to light a fire under you.