Performance issue with pixel/channel arithmetics
- Dominant language
- C++
- Stars
- 199
- Forks
- 171
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 10
Description
### Minimal Working Example (in C++)
Here is a micro-benchmark written with [Google Benchmark](https://github.com/google/benchmark) that compares the performance of a simple plus operation on every pixels of an grayscale image:
```c++
#include
#include
#include
#include
#include
#include
using namespace boost::gil;
static void std_algo(benchmark::State& state)
{
std::vector img(1024 * 1024, 0);
for (auto _ : state)
// The code to benchmark
for (auto&& p : img)
p += 1;
if (!std::all_of(img.begin(), img.end(), [&state](auto p) { return p == state.iterations(); }))
state.SkipWithError("std_algo wrong result");
}
BENCHMARK(std_algo);
static void gil_algo(benchmark::State& state)
{
using namespace std::placeholders;
namespace gil = boost::gil;
gil::gray16_image_t img(1024, 1024, gray16_pixel_t{0});
//Pixel operation
auto op = std::bind(
gil::pixel_plus_t(),
_1, gray16_pixel_t{1});
for (auto _ : state)
// The code to benchmark
gil::transform_pixels(gil::const_view(img), gil::view(img), op);
if (!std::all_of(gil::view(img).begin(), gil::view(img).end(), [&state](auto p) { return p == state.iterations(); }))
state.SkipWithError("gil_algo wrong result");
}
BENCHMARK(gil_algo);
BENCHMARK_MAIN();
```
### Actual behavior
With MSVC, the gil version is an order of magnitude slower than the reference implementation. It looks like the metaprogramming used for unrolling of the channel arithmetic confuses the optimizer.
```
Run on (4 X 3408 MHz CPU s)
CPU Caches:
L1 Data 32K (x4)
L1 Instruction 32K (x4)
L2 Unified 262K (x4)
L3 Unified 6291K (x1)
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
std_algo 56466 ns 57199 ns 11200
gil_algo 329919 ns 329641 ns 2133
```
On the other hand, GCC 7.3 performs much better with very little overhead.
```
Run on (4 X 3408 MHz CPU s)
--------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------
std_algo 74206 ns 74986 ns 8960
gil_algo 81015 ns 81961 ns 8960
```
### Expected behavior
Run time should be about the same.
Is there any interest in adding microbenchmark to the project? I see that there is already a [performance test suite](https://github.com/boostorg/gil/blob/develop/test/performance.cpp) but I am not sure about its coverage and how it is monitored.
### Environment
- Boost version 1.69
- Compiler version: MSVC 2017
- Build settings: /O2 /Ob2 /arch:AVX2
Contributor guide
Assessment
This issue has not been assessed yet.