1 /*
2 *  CSV Display module for the hash benchmark program
3 *  Part of the xxHash project
4 *  Copyright (C) 2019-2020 Yann Collet
5 *
6 *  GPL v2 License
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License along
19 *  with this program; if not, write to the Free Software Foundation, Inc.,
20 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *  You can contact the author at :
23 *  - xxHash homepage : https://www.xxhash.com
24 *  - xxHash source repository : https://github.com/Cyan4973/xxHash
25 */
26 
27 
28 /* ===  Dependencies  === */
29 
30 #include <stdlib.h>   /* rand */
31 #include <stdio.h>    /* printf */
32 #include <assert.h>
33 
34 #include "benchHash.h"
35 #include "bhDisplay.h"
36 
37 
38 /* ===  benchmark large input  === */
39 
40 #define MB_UNIT           1000000
41 #define BENCH_LARGE_ITER_MS   490
42 #define BENCH_LARGE_TOTAL_MS 1010
bench_oneHash_largeInput(Bench_Entry hashDesc,int minlog,int maxlog)43 static void bench_oneHash_largeInput(Bench_Entry hashDesc, int minlog, int maxlog)
44 {
45     printf("%-7s", hashDesc.name);
46     for (int sizelog=minlog; sizelog<=maxlog; sizelog++) {
47         size_t const inputSize = (size_t)1 << sizelog;
48         double const nbhps = bench_hash(hashDesc.hash, BMK_throughput,
49                                         inputSize, BMK_fixedSize,
50                                         BENCH_LARGE_TOTAL_MS, BENCH_LARGE_ITER_MS);
51         printf(",%6.0f", nbhps * inputSize / MB_UNIT); fflush(NULL);
52     }
53     printf("\n");
54 }
55 
bench_largeInput(Bench_Entry const * hashDescTable,int nbHashes,int minlog,int maxlog)56 void bench_largeInput(Bench_Entry const* hashDescTable, int nbHashes, int minlog, int maxlog)
57 {
58     assert(maxlog <  31);
59     assert(minlog >=  0);
60     printf("benchmarking large inputs : from %u bytes (log%i) to %u MB (log%i) \n",
61         1U << minlog, minlog,
62         (1U << maxlog) >> 20, maxlog);
63     for (int i=0; i<nbHashes; i++)
64         bench_oneHash_largeInput(hashDescTable[i], minlog, maxlog);
65 }
66 
67 
68 
69 /* ===  Benchmark small inputs  === */
70 
71 #define BENCH_SMALL_ITER_MS   170
72 #define BENCH_SMALL_TOTAL_MS  490
bench_throughput_oneHash_smallInputs(Bench_Entry hashDesc,size_t sizeMin,size_t sizeMax)73 static void bench_throughput_oneHash_smallInputs(Bench_Entry hashDesc, size_t sizeMin, size_t sizeMax)
74 {
75     printf("%-7s", hashDesc.name);
76     for (size_t s=sizeMin; s<sizeMax+1; s++) {
77         double const nbhps = bench_hash(hashDesc.hash, BMK_throughput,
78                                         s, BMK_fixedSize,
79                                         BENCH_SMALL_TOTAL_MS, BENCH_SMALL_ITER_MS);
80         printf(",%10.0f", nbhps); fflush(NULL);
81     }
82     printf("\n");
83 }
84 
bench_throughput_smallInputs(Bench_Entry const * hashDescTable,int nbHashes,size_t sizeMin,size_t sizeMax)85 void bench_throughput_smallInputs(Bench_Entry const* hashDescTable, int nbHashes, size_t sizeMin, size_t sizeMax)
86 {
87     printf("Throughput small inputs of fixed size (from %zu to %zu bytes): \n",
88             sizeMin, sizeMax);
89     for (int i=0; i<nbHashes; i++)
90         bench_throughput_oneHash_smallInputs(hashDescTable[i], sizeMin, sizeMax);
91 }
92 
93 
94 
95 /* ===   Latency measurements (small keys)   === */
96 
bench_latency_oneHash_smallInputs(Bench_Entry hashDesc,size_t size_min,size_t size_max)97 static void bench_latency_oneHash_smallInputs(Bench_Entry hashDesc, size_t size_min, size_t size_max)
98 {
99     printf("%-7s", hashDesc.name);
100     for (size_t s=size_min; s<size_max+1; s++) {
101         double const nbhps = bench_hash(hashDesc.hash, BMK_latency,
102                                         s, BMK_fixedSize,
103                                         BENCH_SMALL_TOTAL_MS, BENCH_SMALL_ITER_MS);
104         printf(",%10.0f", nbhps); fflush(NULL);
105     }
106     printf("\n");
107 }
108 
bench_latency_smallInputs(Bench_Entry const * hashDescTable,int nbHashes,size_t size_min,size_t size_max)109 void bench_latency_smallInputs(Bench_Entry const* hashDescTable, int nbHashes, size_t size_min, size_t size_max)
110 {
111     printf("Latency for small inputs of fixed size : \n");
112     for (int i=0; i<nbHashes; i++)
113         bench_latency_oneHash_smallInputs(hashDescTable[i], size_min, size_max);
114 }
115 
116 
117 /* ===   Random input Length   === */
118 
bench_randomInputLength_withOneHash(Bench_Entry hashDesc,size_t size_min,size_t size_max)119 static void bench_randomInputLength_withOneHash(Bench_Entry hashDesc, size_t size_min, size_t size_max)
120 {
121     printf("%-7s", hashDesc.name);
122     for (size_t s=size_min; s<size_max+1; s++) {
123         srand((unsigned)s);   /* ensure random sequence of length will be the same for a given s */
124         double const nbhps = bench_hash(hashDesc.hash, BMK_throughput,
125                                         s, BMK_randomSize,
126                                         BENCH_SMALL_TOTAL_MS, BENCH_SMALL_ITER_MS);
127         printf(",%10.0f", nbhps); fflush(NULL);
128     }
129     printf("\n");
130 }
131 
bench_throughput_randomInputLength(Bench_Entry const * hashDescTable,int nbHashes,size_t size_min,size_t size_max)132 void bench_throughput_randomInputLength(Bench_Entry const* hashDescTable, int nbHashes, size_t size_min, size_t size_max)
133 {
134     printf("benchmarking random size inputs [1-N] : \n");
135     for (int i=0; i<nbHashes; i++)
136         bench_randomInputLength_withOneHash(hashDescTable[i], size_min, size_max);
137 }
138 
139 
140 /* ===   Latency with Random input Length   === */
141 
bench_latency_oneHash_randomInputLength(Bench_Entry hashDesc,size_t size_min,size_t size_max)142 static void bench_latency_oneHash_randomInputLength(Bench_Entry hashDesc, size_t size_min, size_t size_max)
143 {
144     printf("%-7s", hashDesc.name);
145     for (size_t s=size_min; s<size_max+1; s++) {
146         srand((unsigned)s);   /* ensure random sequence of length will be the same for a given s */
147         double const nbhps = bench_hash(hashDesc.hash, BMK_latency,
148                                         s, BMK_randomSize,
149                                         BENCH_SMALL_TOTAL_MS, BENCH_SMALL_ITER_MS);
150         printf(",%10.0f", nbhps); fflush(NULL);
151     }
152     printf("\n");
153 }
154 
bench_latency_randomInputLength(Bench_Entry const * hashDescTable,int nbHashes,size_t size_min,size_t size_max)155 void bench_latency_randomInputLength(Bench_Entry const* hashDescTable, int nbHashes, size_t size_min, size_t size_max)
156 {
157     printf("Latency for small inputs of random size [1-N] : \n");
158     for (int i=0; i<nbHashes; i++)
159         bench_latency_oneHash_randomInputLength(hashDescTable[i], size_min, size_max);
160 }
161