RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
DeflateDecompressorBenchmark.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2017 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
22#include "adt/Casts.h"
23#include "adt/Point.h"
24#include "bench/Common.h"
25#include "common/Common.h"
26#include "common/RawImage.h"
27#include "io/Buffer.h"
28#include <cassert>
29#include <cstddef>
30#include <cstdint>
31#include <memory>
32#include <type_traits>
33#include <vector>
34#include <zconf.h>
35#include <zlib.h>
36#include <benchmark/benchmark.h>
37
38#ifndef NDEBUG
39#include <limits>
40#endif
41
43using rawspeed::DeflateDecompressor;
44
45namespace {
46
47template <size_t N> using BPS = std::integral_constant<size_t, N>;
48template <int N> using Pf = std::integral_constant<int, N>;
49
50template <typename BPS>
51std::vector<uint8_t> compressChunk(const rawspeed::RawImage& mRaw,
52 uLong* bufSize) {
53 static_assert(BPS::value > 0, "bad bps");
54 static_assert(rawspeed::isAligned(BPS::value, 8), "not byte count");
55
56 const uLong uncompressedLength = BPS::value * mRaw->dim.x * mRaw->dim.y / 8UL;
57 assert(uncompressedLength > 0);
58 assert(uncompressedLength <= std::numeric_limits<Buffer::size_type>::max());
59
60 *bufSize = compressBound(uncompressedLength);
61 assert(*bufSize > 0);
62 assert(*bufSize <= std::numeric_limits<Buffer::size_type>::max());
63
64 const std::vector<uint8_t> uBuf(uncompressedLength);
65 std::vector<uint8_t> cBuf(*bufSize);
66
67 const int err =
68 compress(cBuf.data(), bufSize, uBuf.data(), uncompressedLength);
69 if (err != Z_OK)
70 throw;
71
72 assert(compressBound(uncompressedLength) >= *bufSize);
73
74 return cBuf;
75}
76
77template <typename BPS, typename Pf>
78inline void BM_DeflateDecompressor(benchmark::State& state) {
79 static_assert(BPS::value > 0, "bad bps");
80 static_assert(rawspeed::isAligned(BPS::value, 8), "not byte count");
81
82 const auto dim = areaToRectangle(state.range(0));
84
85 uLong cBufSize;
86 const std::vector<uint8_t> cBuf = compressChunk<BPS>(mRaw, &cBufSize);
87 assert(cBufSize > 0);
88
89 Buffer buf(cBuf.data(), rawspeed::implicit_cast<Buffer::size_type>(cBufSize));
90 assert(buf.getSize() == cBufSize);
91
92 int predictor = 0;
93 switch (Pf::value) {
94 case 1:
95 predictor = 3;
96 break;
97 case 2:
98 predictor = 34894;
99 break;
100 case 4:
101 predictor = 34895;
102 break;
103 default:
104 __builtin_unreachable();
105 break;
106 }
107
108 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
109 std::unique_ptr<unsigned char[]> uBuffer;
110
111 for (auto _ : state) {
112 DeflateDecompressor d(buf, mRaw, predictor, BPS::value);
113
114 d.decode(&uBuffer, mRaw->dim, mRaw->dim, {0, 0});
115 }
116
117 state.SetComplexityN(dim.area());
118 state.SetItemsProcessed(state.complexity_length_n() * state.iterations());
119 state.SetBytesProcessed(BPS::value * state.items_processed() / 8);
120}
121
122inline void CustomArgs(benchmark::internal::Benchmark* b) {
123 if (benchmarkDryRun()) {
124 static constexpr int L2dByteSize = 512U * (1U << 10U);
125 b->Arg((L2dByteSize / (32 / 8)) / 4);
126 return;
127 }
128
129 b->RangeMultiplier(2);
130 // FIXME: appears to not like 1GPix+ buffers
131 if constexpr ((true)) {
132 b->Arg(128 << 20);
133 } else {
134 b->Range(1, 1023 << 20)->Complexity(benchmark::oN);
135 }
136 b->Unit(benchmark::kMillisecond);
137}
138
139#define GEN_E(s, f) \
140 BENCHMARK_TEMPLATE(BM_DeflateDecompressor, BPS<s>, Pf<f>)->Apply(CustomArgs);
141#define GEN_PFS(s) GEN_E(s, 1) GEN_E(s, 2) GEN_E(s, 4)
142#define GEN_PSS() GEN_PFS(16) GEN_PFS(24) GEN_PFS(32)
143
144GEN_PSS()
145
146} // namespace
147
BENCHMARK_MAIN()
iPoint2D dim(rawspeed::implicit_cast< int >(ceil(sqSide *sqARatio)), rawspeed::implicit_cast< int >(ceil(sqSide/sqARatio)))
Definition Common.cpp:55
assert(dim.area() >=area)
bool RAWSPEED_READNONE benchmarkDryRun()
rawspeed::iPoint2D RAWSPEED_READNONE areaToRectangle(uint64_t area, rawspeed::iPoint2D aspect={2, 2})
size_type RAWSPEED_READONLY getSize() const
Definition Buffer.h:115
static RawImage create(RawImageType type=RawImageType::UINT16)
Definition RawImage.h:265
value_type x
Definition Point.h:102
value_type y
Definition Point.h:103
std::vector< uint8_t > compressChunk(const rawspeed::RawImage &mRaw, uLong *bufSize)
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
constexpr RAWSPEED_READNONE bool isAligned(T value, size_t multiple)
Definition Common.h:151