Pillow-SIMD: Faster Image Processing with Pillow

Pillow-SIMD: Faster Image Processing with PillowTranslated by Python Tribe (python.freelycode.com), unauthorized reproduction is prohibited, sharing is welcome.

Pillow-SIMD is a fork of Pillow (which itself is a fork of PIL). To learn more about Pillow, please refer to the relevant documentation and changelog and contribute to its development. Why SIMD? There are many ways to improve image processing performance. You can choose better algorithms to accomplish the same task, implement existing algorithms more efficiently, or utilize more computational resources for processing. You can use more efficient algorithms, such as convolution-based Gaussian blur instead of sequential box filtering. However, such improvements are very limited. When resources are available, you would certainly want to use more computational resources (through parallelization) for processing. But it would be even better to increase processing speed using the same resources, and that is precisely what SIMD excels at. SIMD stands for Single Instruction, Multiple Data. It is a method of performing the same operation on massive data. Modern CPUs have different SIMD instruction sets, such as MMX, SSE-SSE4, AVX, AVX2, AVX512, and NEON. Currently, Pillow-SIMD can be compiled using SSE4 (default) and AVX2. Current Status Pillow-SIMD is available for production environments and has been running on Uploadcare servers for over a year. Uploadcare is a SaaS company specializing in image cloud processing and cloud storage, and is a major sponsor of the Pillow-SIMD project. Currently, the following work is being accelerated: * Resizing (convolution-based resampling): SSE4, AVX2 * Gaussian and box blurring: SSE4 Benchmark The numbers in the table represent the amount of source image processing in millions of pixels per second. For example, if resizing a 7712×4352 image is completed in 0.5 seconds, the result is 61.7 Mpx/s. * ImageMagick 6.9.3-8 Q8 x86_64 * Pillow 3.2.0 * Pillow-SIMD 3.2.0.post1

Source Operation Filter IM Pillow SIMD SSE4 SIMD AVX2
7712×4352 Resize to 16×16 Bilinear 27.0 217 456 545
Bicubic 10.9 115 240 278
Lanczos 6.6 76.1 162 194
Resize to 320×180 Bilinear 32.0 166 354 410
Bicubic 16.5 92.3 198 204
Lanczos 11.0 63.2 133 147
Resize to 2048×1155 Bilinear 20.7 87.6 202 217
Bicubic 12.2 65.7 126 130
Lanczos 8.7 41.3 88.2 95.6
Blur 1px 8.1 17.1 37.8
10px 2.6 17.4 39.0
100px 0.3 17.2 39.0
1920×1280 Resize to 16×16 Bilinear 41.6 196 422 489
Bicubic 18.9 102 225 263
Lanczos 13.7 68.6 118 167
Resize to 320×180 Bilinear 27.6 111 196 197
Bicubic 14.5 66.3 154 162
Lanczos 9.8 44.3 102 107
Resize to 2048×1155 Bilinear 9.1 20.7 71.3 72.6
Bicubic 6.3 16.9 49.3 54.3
Lanczos 4.7 14.6 36.8 40.6
Blur 1px 8.7 16.2 35.7
10px 2.8 16.7 35.4
100px 0.4 16.4 36.2

Conclusion Pillow is generally faster than ImageMagick, and Pillow-SIMD is 2-2.5 times faster than Pillow. Overall, using AVX2, Pillow-SIMD is nearly 10 times faster than ImageMagick. Testing Method All tests were conducted in a single-threaded environment on 64-bit Ubuntu 14.04, with an Intel Core i5 4258U CPU utilizing AVX2. The performance of ImageMagick was measured using the command line tool with -verbose and -bench parameters. I used command line testing because it was the simplest way to test the latest version, and all operations produced consistent results. Compliance of resampling filters: *PIL.Image.BILINEAR == Triangle *PIL.Image.BICUBIC == Catrom *PIL.Image.LANCZOS == Lanczos In ImageMagick, the radius for Gaussian blur is referred to as Sigma, and the second parameter is the radius. In fact, there should not be an additional parameter for Gaussian blur because when the radius is too small, there is no Gaussian blur. When the radius is too large, it only slows down processing without any other benefits. For this test, I set the radius to 2.5 times Sigma. This is the script used for testing: https://gist.github.com/homm/f9b8d8a84a57a7e51f9c2a5828e40e63 Why Pillow is Fast High-quality resizing and blurring methods were used for all benchmarks. The results are nearly lossless. The difference lies only in whether the algorithm is efficient. Resampling in Pillow uses minimal floating-point numbers, pre-calculated coefficients, and is cache-aware, rewritten in version 2.7. Why Pillow-SIMD is Faster This is due to SIMD’s implementation of performance-enhancing methods. * Efficient collaboration with memory. Nowadays, every pixel is read from memory into SSE registers, where each SSE register can process 4 pixels simultaneously. * Integer-based operations. Experimental results show that integer-based calculations do not affect quality and can improve non-SIMD code performance by 50%. * Aligned pixel allocation. It is well-known that SIMD’s load and store commands handle aligned memory very well. Why Not Merge SIMD into Original Pillow Well, this is not a simple task. First, Pillow supports most architectures, not just x86. Even on x86 platforms, Pillow is released as compiled binaries. To integrate SIMD into the compiled binaries, we need to check the CPU’s capabilities. To compile code with runtime detection, we need to pass the -mavx2 option to the compiler. This automatically activates all if (__AVX2__) and below conditional statements. SIMD instructions under this condition are even present in the C standard library, which do not require any runtime detection. Now, I do not know how to include SIMD instructions in the code while removing runtime detection. Installation Generally, you would use pip install pillow-simd as usual. If you are using an SSE4 CPU, everything will go smoothly. Be sure to uninstall the original Pillow package before installing. If you want to use a version that supports AVX2, you need to provide additional flags to the C compiler. The simplest way is to define the CC variable at compile time. $ pip uninstall pillow $ CC=”cc -mavx2″ pip install -U –force-reinstall pillow-simd Contribute to Pillow-SIMD Pillow-SIMD and Pillow are two independent projects. Please report defects and optimizations unrelated to SIMD to Pillow. All defects and fixes in Pillow will automatically appear in the next version of Pillow-SIMD.

Original English text: https://github.com/uploadcare/pillow-simd#readme Translator: zmq518

Leave a Comment