]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - programs/bench.h
import zstd 1.3.7
[FreeBSD/FreeBSD.git] / programs / bench.h
1 /*
2  * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10
11 #if defined (__cplusplus)
12 extern "C" {
13 #endif
14
15 #ifndef BENCH_H_121279284357
16 #define BENCH_H_121279284357
17
18 /* ===  Dependencies  === */
19 #include <stddef.h>   /* size_t */
20 #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_compressionParameters */
21 #include "zstd.h"     /* ZSTD_compressionParameters */
22
23
24 /* ===  Constants  === */
25
26 #define MB_UNIT 1000000
27
28
29 /* ===  Benchmark functions  === */
30
31 /* Creates a variant `typeName`, able to express "error or valid result".
32  * Functions with return type `typeName`
33  * must first check if result is valid, using BMK_isSuccessful_*(),
34  * and only then can extract `baseType`.
35  */
36 #define VARIANT_ERROR_RESULT(baseType, variantName)  \
37                                              \
38 typedef struct {                             \
39     baseType internal_never_use_directly;    \
40     int tag;                                 \
41 } variantName
42
43
44 typedef struct {
45     size_t cSize;
46     unsigned long long cSpeed;   /* bytes / sec */
47     unsigned long long dSpeed;
48     size_t cMem;                 /* memory usage during compression */
49 } BMK_benchResult_t;
50
51 VARIANT_ERROR_RESULT(BMK_benchResult_t, BMK_benchOutcome_t);
52
53 /* check first if the return structure represents an error or a valid result */
54 int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome);
55
56 /* extract result from variant type.
57  * note : this function will abort() program execution if result is not valid
58  *        check result validity first, by using BMK_isSuccessful_benchOutcome()
59  */
60 BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome);
61
62
63 /*! BMK_benchFiles() -- called by zstdcli */
64 /*  Loads files from fileNamesTable into memory,
65  *  and an optional dictionary from dictFileName (can be NULL),
66  *  then uses benchMem().
67  *  fileNamesTable - name of files to benchmark.
68  *  nbFiles - number of files (size of fileNamesTable), must be > 0.
69  *  dictFileName - name of dictionary file to load.
70  *  cLevel - compression level to benchmark, errors if invalid.
71  *  compressionParams - advanced compression Parameters.
72  *  displayLevel - what gets printed:
73  *      0 : no display;
74  *      1 : errors;
75  *      2 : + result + interaction + warnings;
76  *      3 : + information;
77  *      4 : + debug
78  * @return:
79  *      a variant, which expresses either an error, or a valid result.
80  *      Use BMK_isSuccessful_benchOutcome() to check if function was successful.
81  *      If yes, extract the valid result with BMK_extract_benchResult(),
82  *      it will contain :
83  *          .cSpeed: compression speed in bytes per second,
84  *          .dSpeed: decompression speed in bytes per second,
85  *          .cSize : compressed size, in bytes
86  *          .cMem  : memory budget required for the compression context
87  */
88 BMK_benchOutcome_t BMK_benchFiles(
89                    const char* const * fileNamesTable, unsigned nbFiles,
90                    const char* dictFileName,
91                    int cLevel, const ZSTD_compressionParameters* compressionParams,
92                    int displayLevel);
93
94
95 typedef enum {
96     BMK_both = 0,
97     BMK_decodeOnly = 1,
98     BMK_compressOnly = 2
99 } BMK_mode_t;
100
101 typedef struct {
102     BMK_mode_t mode;            /* 0: all, 1: compress only 2: decode only */
103     unsigned nbSeconds;         /* default timing is in nbSeconds */
104     size_t blockSize;           /* Maximum size of each block*/
105     unsigned nbWorkers;         /* multithreading */
106     unsigned realTime;          /* real time priority */
107     int additionalParam;        /* used by python speed benchmark */
108     unsigned ldmFlag;           /* enables long distance matching */
109     unsigned ldmMinMatch;       /* below: parameters for long distance matching, see zstd.1.md */
110     unsigned ldmHashLog;
111     unsigned ldmBucketSizeLog;
112     unsigned ldmHashEveryLog;
113 } BMK_advancedParams_t;
114
115 /* returns default parameters used by nonAdvanced functions */
116 BMK_advancedParams_t BMK_initAdvancedParams(void);
117
118 /*! BMK_benchFilesAdvanced():
119  *  Same as BMK_benchFiles(),
120  *  with more controls, provided through advancedParams_t structure */
121 BMK_benchOutcome_t BMK_benchFilesAdvanced(
122                    const char* const * fileNamesTable, unsigned nbFiles,
123                    const char* dictFileName,
124                    int cLevel, const ZSTD_compressionParameters* compressionParams,
125                    int displayLevel, const BMK_advancedParams_t* adv);
126
127 /*! BMK_syntheticTest() -- called from zstdcli */
128 /*  Generates a sample with datagen, using compressibility argument */
129 /*  cLevel - compression level to benchmark, errors if invalid
130  *  compressibility - determines compressibility of sample
131  *  compressionParams - basic compression Parameters
132  *  displayLevel - see benchFiles
133  *  adv - see advanced_Params_t
134  * @return:
135  *      a variant, which expresses either an error, or a valid result.
136  *      Use BMK_isSuccessful_benchOutcome() to check if function was successful.
137  *      If yes, extract the valid result with BMK_extract_benchResult(),
138  *      it will contain :
139  *          .cSpeed: compression speed in bytes per second,
140  *          .dSpeed: decompression speed in bytes per second,
141  *          .cSize : compressed size, in bytes
142  *          .cMem  : memory budget required for the compression context
143  */
144 BMK_benchOutcome_t BMK_syntheticTest(
145                               int cLevel, double compressibility,
146                               const ZSTD_compressionParameters* compressionParams,
147                               int displayLevel, const BMK_advancedParams_t* adv);
148
149
150
151 /* ===  Benchmark Zstandard in a memory-to-memory scenario  === */
152
153 /** BMK_benchMem() -- core benchmarking function, called in paramgrill
154  *  applies ZSTD_compress_generic() and ZSTD_decompress_generic() on data in srcBuffer
155  *  with specific compression parameters provided by other arguments using benchFunction
156  *  (cLevel, comprParams + adv in advanced Mode) */
157 /*  srcBuffer - data source, expected to be valid compressed data if in Decode Only Mode
158  *  srcSize - size of data in srcBuffer
159  *  fileSizes - srcBuffer is considered cut into 1+ segments, to compress separately.
160  *              note : sum(fileSizes) must be == srcSize.  (<== ensure it's properly checked)
161  *  nbFiles - nb of segments
162  *  cLevel - compression level
163  *  comprParams - basic compression parameters
164  *  dictBuffer - a dictionary if used, null otherwise
165  *  dictBufferSize - size of dictBuffer, 0 otherwise
166  *  diplayLevel - see BMK_benchFiles
167  *  displayName - name used by display
168  * @return:
169  *      a variant, which expresses either an error, or a valid result.
170  *      Use BMK_isSuccessful_benchOutcome() to check if function was successful.
171  *      If yes, extract the valid result with BMK_extract_benchResult(),
172  *      it will contain :
173  *          .cSpeed: compression speed in bytes per second,
174  *          .dSpeed: decompression speed in bytes per second,
175  *          .cSize : compressed size, in bytes
176  *          .cMem  : memory budget required for the compression context
177  */
178 BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
179                         const size_t* fileSizes, unsigned nbFiles,
180                         int cLevel, const ZSTD_compressionParameters* comprParams,
181                         const void* dictBuffer, size_t dictBufferSize,
182                         int displayLevel, const char* displayName);
183
184 /* BMK_benchMemAdvanced() : same as BMK_benchMem()
185  * with following additional options :
186  * dstBuffer - destination buffer to write compressed output in, NULL if none provided.
187  * dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL
188  * adv = see advancedParams_t
189  */
190 BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
191                         void* dstBuffer, size_t dstCapacity,
192                         const size_t* fileSizes, unsigned nbFiles,
193                         int cLevel, const ZSTD_compressionParameters* comprParams,
194                         const void* dictBuffer, size_t dictBufferSize,
195                         int displayLevel, const char* displayName,
196                         const BMK_advancedParams_t* adv);
197
198
199
200 /* ====  Benchmarking any function, iterated on a set of blocks  ==== */
201
202 typedef struct {
203     unsigned long long nanoSecPerRun;  /* time per iteration */
204     size_t sumOfReturn;       /* sum of return values */
205 } BMK_runTime_t;
206
207 VARIANT_ERROR_RESULT(BMK_runTime_t, BMK_runOutcome_t);
208
209 /* check first if the return structure represents an error or a valid result */
210 int BMK_isSuccessful_runOutcome(BMK_runOutcome_t outcome);
211
212 /* extract result from variant type.
213  * note : this function will abort() program execution if result is not valid
214  *        check result validity first, by using BMK_isSuccessful_runOutcome()
215  */
216 BMK_runTime_t BMK_extract_runTime(BMK_runOutcome_t outcome);
217
218
219
220 typedef size_t (*BMK_benchFn_t)(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* customPayload);
221 typedef size_t (*BMK_initFn_t)(void* initPayload);
222
223
224 /* BMK_benchFunction() :
225  * This function times the execution of 2 argument functions, benchFn and initFn  */
226
227 /* benchFn - (*benchFn)(srcBuffers[i], srcSizes[i], dstBuffers[i], dstCapacities[i], benchPayload)
228  *      is run nbLoops times
229  * initFn - (*initFn)(initPayload) is run once per benchmark, at the beginning.
230  *      This argument can be NULL, in which case nothing is run.
231  * blockCount - number of blocks. Size of all array parameters : srcBuffers, srcSizes, dstBuffers, dstCapacities, blockResults
232  * srcBuffers - an array of buffers to be operated on by benchFn
233  * srcSizes - an array of the sizes of above buffers
234  * dstBuffers - an array of buffers to be written into by benchFn
235  * dstCapacities - an array of the capacities of above buffers
236  * blockResults - Optional: store the return value of benchFn for each block. Use NULL if this result is not requested.
237  * nbLoops - defines number of times benchFn is run.
238  * @return: a variant, which express either an error, or can generate a valid BMK_runTime_t result.
239  *          Use BMK_isSuccessful_runOutcome() to check if function was successful.
240  *          If yes, extract the result with BMK_extract_runTime(),
241  *          it will contain :
242  *              .sumOfReturn : the sum of all return values of benchFn through all of blocks
243  *              .nanoSecPerRun : time per run of benchFn + (time for initFn / nbLoops)
244  *          .sumOfReturn is generally intended for functions which return a # of bytes written into dstBuffer,
245  *              in which case, this value will be the total amount of bytes written into dstBuffer.
246  */
247 BMK_runOutcome_t BMK_benchFunction(
248                         BMK_benchFn_t benchFn, void* benchPayload,
249                         BMK_initFn_t initFn, void* initPayload,
250                         size_t blockCount,
251                         const void *const * srcBuffers, const size_t* srcSizes,
252                         void *const * dstBuffers, const size_t* dstCapacities,
253                         size_t* blockResults,
254                         unsigned nbLoops);
255
256
257
258 /* ====  Benchmark any function, providing intermediate results  ==== */
259
260 /* state information tracking benchmark session */
261 typedef struct BMK_timedFnState_s BMK_timedFnState_t;
262
263 /* BMK_createTimedFnState() and BMK_resetTimedFnState() :
264  * Create/Set BMK_timedFnState_t for next benchmark session,
265  * which shall last a minimum of total_ms milliseconds,
266  * producing intermediate results, paced at interval of (approximately) run_ms.
267  */
268 BMK_timedFnState_t* BMK_createTimedFnState(unsigned total_ms, unsigned run_ms);
269 void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, unsigned run_ms);
270 void BMK_freeTimedFnState(BMK_timedFnState_t* state);
271
272
273 /* Tells if duration of all benchmark runs has exceeded total_ms
274  */
275 int BMK_isCompleted_TimedFn(const BMK_timedFnState_t* timedFnState);
276
277
278 /* BMK_benchTimedFn() :
279  * Similar to BMK_benchFunction(), most arguments being identical.
280  * Automatically determines `nbLoops` so that each result is regularly produced at interval of about run_ms.
281  * Note : minimum `nbLoops` is 1, therefore a run may last more than run_ms, and possibly even more than total_ms.
282  * Usage - initialize timedFnState, select benchmark duration (total_ms) and each measurement duration (run_ms)
283  *         call BMK_benchTimedFn() repetitively, each measurement is supposed to last about run_ms
284  *         Check if total time budget is spent or exceeded, using BMK_isCompleted_TimedFn()
285  */
286 BMK_runOutcome_t BMK_benchTimedFn(
287                     BMK_timedFnState_t* timedFnState,
288                     BMK_benchFn_t benchFn, void* benchPayload,
289                     BMK_initFn_t initFn, void* initPayload,
290                     size_t blockCount,
291                     const void *const * srcBlockBuffers, const size_t* srcBlockSizes,
292                     void *const * dstBlockBuffers, const size_t* dstBlockCapacities,
293                     size_t* blockResults);
294
295
296
297
298
299 #endif   /* BENCH_H_121279284357 */
300
301 #if defined (__cplusplus)
302 }
303 #endif