blob: f5aa5e21aecfc0c4253da889b45f84077ab63904 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2010 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38#if 0
39#ifdef __OPTIMIZE__
40#undef CLIB_DEBUG
41#endif
42#endif
43
44#include <vppinfra/bitmap.h>
45#include <vppinfra/error.h>
46#include <vppinfra/os.h>
47#include <vppinfra/random.h>
48#include <vppinfra/time.h>
49#include <vppinfra/vhash.h>
50
51#ifdef CLIB_HAVE_VEC128
52
Dave Barachc3799992016-08-15 11:12:27 -040053typedef struct
54{
Ed Warnickecb9cada2015-12-08 15:45:58 -070055 u32 n_iter;
56 u32 seed;
57 u32 verbose;
58 u32 n_keys;
59 u32 log2_size;
60 u32 n_key_u32;
61
62 u32 n_vectors_div_4;
63 u32 n_vectors_mod_4;
64
Dave Barachc3799992016-08-15 11:12:27 -040065 u32 *keys;
66 u32 *results;
Ed Warnickecb9cada2015-12-08 15:45:58 -070067
Dave Barachc3799992016-08-15 11:12:27 -040068 u32 *vhash_get_key_indices;
69 u32 *vhash_get_results;
Ed Warnickecb9cada2015-12-08 15:45:58 -070070
Dave Barachc3799992016-08-15 11:12:27 -040071 u32 *vhash_key_indices;
72 u32 *vhash_results;
Ed Warnickecb9cada2015-12-08 15:45:58 -070073
74 vhash_t vhash;
75
Dave Barachc3799992016-08-15 11:12:27 -040076 uword **key_hash;
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
Dave Barachc3799992016-08-15 11:12:27 -040078 struct
79 {
Ed Warnickecb9cada2015-12-08 15:45:58 -070080 u64 n_clocks;
81 u64 n_vectors;
82 u64 n_calls;
83 } get_stats, set_stats, unset_stats;
84} test_vhash_main_t;
85
86always_inline u32
Dave Barachc3799992016-08-15 11:12:27 -040087test_vhash_key_gather (void *_tm, u32 vi, u32 wi, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -070088{
Dave Barachc3799992016-08-15 11:12:27 -040089 test_vhash_main_t *tm = _tm;
Ed Warnickecb9cada2015-12-08 15:45:58 -070090 ASSERT (n_key_u32s == tm->n_key_u32);
91 ASSERT (wi < n_key_u32s);
92 vi = vec_elt (tm->vhash_key_indices, vi);
93 return vec_elt (tm->keys, vi * n_key_u32s + wi);
94}
95
96always_inline u32x4
Dave Barachc3799992016-08-15 11:12:27 -040097test_vhash_4key_gather (void *_tm, u32 vi, u32 wi, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -070098{
Dave Barachc3799992016-08-15 11:12:27 -040099 test_vhash_main_t *tm = _tm;
100 u32 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700101 u32x4_union_t x;
102
103 ASSERT (n_key_u32s == tm->n_key_u32);
104 ASSERT (wi < n_key_u32s);
105
106 p = vec_elt_at_index (tm->vhash_key_indices, vi + 0);
107 x.as_u32[0] = tm->keys[p[0] * n_key_u32s + wi];
108 x.as_u32[1] = tm->keys[p[1] * n_key_u32s + wi];
109 x.as_u32[2] = tm->keys[p[2] * n_key_u32s + wi];
110 x.as_u32[3] = tm->keys[p[3] * n_key_u32s + wi];
111 return x.as_u32x4;
112}
113
114always_inline u32
Dave Barachc3799992016-08-15 11:12:27 -0400115test_vhash_get_result (void *_tm,
116 u32 vector_index, u32 result_index, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700117{
Dave Barachc3799992016-08-15 11:12:27 -0400118 test_vhash_main_t *tm = _tm;
119 u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120 p[0] = result_index;
121 return result_index;
122}
123
124always_inline u32x4
Dave Barachc3799992016-08-15 11:12:27 -0400125test_vhash_get_4result (void *_tm,
126 u32 vector_index, u32x4 results, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127{
Dave Barachc3799992016-08-15 11:12:27 -0400128 test_vhash_main_t *tm = _tm;
129 u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
130 *(u32x4 *) p = results;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700131 return results;
132}
133
134always_inline u32
Dave Barachc3799992016-08-15 11:12:27 -0400135test_vhash_set_result (void *_tm,
136 u32 vector_index, u32 old_result, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700137{
Dave Barachc3799992016-08-15 11:12:27 -0400138 test_vhash_main_t *tm = _tm;
139 u32 *p = vec_elt_at_index (tm->vhash_results, vector_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140 u32 new_result = p[0];
141 p[0] = old_result;
142 return new_result;
143}
144
145always_inline u32
Dave Barachc3799992016-08-15 11:12:27 -0400146test_vhash_unset_result (void *_tm, u32 i, u32 old_result, u32 n_key_u32s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147{
Dave Barachc3799992016-08-15 11:12:27 -0400148 test_vhash_main_t *tm = _tm;
149 u32 *p = vec_elt_at_index (tm->vhash_results, i);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700150 p[0] = old_result;
151 return 0;
152}
153
154#define _(N_KEY_U32) \
155 always_inline u32 \
156 test_vhash_key_gather_##N_KEY_U32 (void * _tm, u32 vi, u32 i) \
157 { return test_vhash_key_gather (_tm, vi, i, N_KEY_U32); } \
158 \
159 always_inline u32x4 \
160 test_vhash_key_gather_4_##N_KEY_U32 (void * _tm, u32 vi, u32 i) \
161 { return test_vhash_4key_gather (_tm, vi, i, N_KEY_U32); } \
162 \
163 clib_pipeline_stage \
164 (test_vhash_gather_keys_stage_##N_KEY_U32, \
165 test_vhash_main_t *, tm, i, \
166 { \
167 vhash_gather_4key_stage \
168 (&tm->vhash, \
169 /* vector_index */ i, \
170 test_vhash_key_gather_4_##N_KEY_U32, \
171 tm, \
172 N_KEY_U32); \
173 }) \
174 \
175 clib_pipeline_stage_no_inline \
176 (test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
177 test_vhash_main_t *, tm, i, \
178 { \
179 vhash_gather_key_stage \
180 (&tm->vhash, \
181 /* vector_index */ tm->n_vectors_div_4, \
182 /* n_vectors */ tm->n_vectors_mod_4, \
183 test_vhash_key_gather_##N_KEY_U32, \
184 tm, \
185 N_KEY_U32); \
186 }) \
187 \
188 clib_pipeline_stage \
189 (test_vhash_hash_finalize_stage_##N_KEY_U32, \
190 test_vhash_main_t *, tm, i, \
191 { \
192 vhash_finalize_stage (&tm->vhash, i, N_KEY_U32); \
193 }) \
194 \
195 clib_pipeline_stage_no_inline \
196 (test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
197 test_vhash_main_t *, tm, i, \
198 { \
199 vhash_finalize_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32); \
200 }) \
201 \
202 clib_pipeline_stage \
203 (test_vhash_get_stage_##N_KEY_U32, \
204 test_vhash_main_t *, tm, i, \
205 { \
206 vhash_get_4_stage (&tm->vhash, \
207 /* vector_index */ i, \
208 test_vhash_get_4result, \
209 tm, N_KEY_U32); \
210 }) \
211 \
212 clib_pipeline_stage_no_inline \
213 (test_vhash_get_mod_stage_##N_KEY_U32, \
214 test_vhash_main_t *, tm, i, \
215 { \
216 vhash_get_stage (&tm->vhash, \
217 /* vector_index */ tm->n_vectors_div_4, \
218 /* n_vectors */ tm->n_vectors_mod_4, \
219 test_vhash_get_result, \
220 tm, N_KEY_U32); \
221 }) \
222 \
223 clib_pipeline_stage \
224 (test_vhash_set_stage_##N_KEY_U32, \
225 test_vhash_main_t *, tm, i, \
226 { \
227 vhash_set_stage (&tm->vhash, \
228 /* vector_index */ i, \
229 /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32), \
230 test_vhash_set_result, \
231 tm, N_KEY_U32); \
232 }) \
233 \
234 clib_pipeline_stage_no_inline \
235 (test_vhash_set_mod_stage_##N_KEY_U32, \
236 test_vhash_main_t *, tm, i, \
237 { \
238 vhash_set_stage (&tm->vhash, \
239 /* vector_index */ tm->n_vectors_div_4, \
240 /* n_vectors */ tm->n_vectors_mod_4, \
241 test_vhash_set_result, \
242 tm, N_KEY_U32); \
243 }) \
244 \
245 clib_pipeline_stage \
246 (test_vhash_unset_stage_##N_KEY_U32, \
247 test_vhash_main_t *, tm, i, \
248 { \
249 vhash_unset_stage (&tm->vhash, \
250 /* vector_index */ i, \
251 /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32), \
252 test_vhash_unset_result, \
253 tm, N_KEY_U32); \
254 }) \
255 \
256 clib_pipeline_stage_no_inline \
257 (test_vhash_unset_mod_stage_##N_KEY_U32, \
258 test_vhash_main_t *, tm, i, \
259 { \
260 vhash_unset_stage (&tm->vhash, \
261 /* vector_index */ tm->n_vectors_div_4, \
262 /* n_vectors */ tm->n_vectors_mod_4, \
263 test_vhash_unset_result, \
264 tm, N_KEY_U32); \
265 })
266
Dave Barachc3799992016-08-15 11:12:27 -0400267_(1);
268_(2);
269_(3);
270_(4);
271_(5);
272_(6);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700273
274#undef _
275
276#define _(N_KEY_U32) \
277 clib_pipeline_stage \
278 (test_vhash_hash_mix_stage_##N_KEY_U32, \
279 test_vhash_main_t *, tm, i, \
280 { \
281 vhash_mix_stage (&tm->vhash, i, N_KEY_U32); \
282 }) \
283 \
284 clib_pipeline_stage_no_inline \
285 (test_vhash_hash_mix_mod_stage_##N_KEY_U32, \
286 test_vhash_main_t *, tm, i, \
287 { \
288 vhash_mix_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32); \
289 })
290
Dave Barachc3799992016-08-15 11:12:27 -0400291_(4);
292_(5);
293_(6);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294
295#undef _
296
Dave Barachc3799992016-08-15 11:12:27 -0400297typedef enum
298{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700299 GET, SET, UNSET,
300} test_vhash_op_t;
301
302static void
303test_vhash_op (test_vhash_main_t * tm,
304 u32 * key_indices,
Dave Barachc3799992016-08-15 11:12:27 -0400305 u32 * results, uword n_keys, test_vhash_op_t op)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700306{
307 vhash_validate_sizes (&tm->vhash, tm->n_key_u32, n_keys);
308
309 tm->vhash_results = results;
310 tm->vhash_key_indices = key_indices;
311 tm->n_vectors_div_4 = n_keys / 4;
312 tm->n_vectors_mod_4 = n_keys % 4;
313
314 if (tm->n_vectors_div_4 > 0)
315 {
316 switch (tm->n_key_u32)
317 {
318 default:
319 ASSERT (0);
320 break;
321
322#define _(N_KEY_U32) \
323 case N_KEY_U32: \
324 if (op == GET) \
325 clib_pipeline_run_3_stage \
326 (tm->n_vectors_div_4, \
327 tm, \
328 test_vhash_gather_keys_stage_##N_KEY_U32, \
329 test_vhash_hash_finalize_stage_##N_KEY_U32, \
330 test_vhash_get_stage_##N_KEY_U32); \
331 else if (op == SET) \
332 clib_pipeline_run_3_stage \
333 (tm->n_vectors_div_4, \
334 tm, \
335 test_vhash_gather_keys_stage_##N_KEY_U32, \
336 test_vhash_hash_finalize_stage_##N_KEY_U32, \
337 test_vhash_set_stage_##N_KEY_U32); \
338 else \
339 clib_pipeline_run_3_stage \
340 (tm->n_vectors_div_4, \
341 tm, \
342 test_vhash_gather_keys_stage_##N_KEY_U32, \
343 test_vhash_hash_finalize_stage_##N_KEY_U32, \
344 test_vhash_unset_stage_##N_KEY_U32); \
345 break;
346
Dave Barachc3799992016-08-15 11:12:27 -0400347 _(1);
348 _(2);
349 _(3);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700350
351#undef _
352
353#define _(N_KEY_U32) \
354 case N_KEY_U32: \
355 if (op == GET) \
356 clib_pipeline_run_4_stage \
357 (tm->n_vectors_div_4, \
358 tm, \
359 test_vhash_gather_keys_stage_##N_KEY_U32, \
360 test_vhash_hash_mix_stage_##N_KEY_U32, \
361 test_vhash_hash_finalize_stage_##N_KEY_U32, \
362 test_vhash_get_stage_##N_KEY_U32); \
363 else if (op == SET) \
364 clib_pipeline_run_4_stage \
365 (tm->n_vectors_div_4, \
366 tm, \
367 test_vhash_gather_keys_stage_##N_KEY_U32, \
368 test_vhash_hash_mix_stage_##N_KEY_U32, \
369 test_vhash_hash_finalize_stage_##N_KEY_U32, \
370 test_vhash_set_stage_##N_KEY_U32); \
371 else \
372 clib_pipeline_run_4_stage \
373 (tm->n_vectors_div_4, \
374 tm, \
375 test_vhash_gather_keys_stage_##N_KEY_U32, \
376 test_vhash_hash_mix_stage_##N_KEY_U32, \
377 test_vhash_hash_finalize_stage_##N_KEY_U32, \
378 test_vhash_unset_stage_##N_KEY_U32); \
379 break;
380
Dave Barachc3799992016-08-15 11:12:27 -0400381 _(4);
382 _(5);
383 _(6);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700384
385#undef _
386 }
387 }
388
389
390 if (tm->n_vectors_mod_4 > 0)
391 {
392 switch (tm->n_key_u32)
393 {
394 default:
395 ASSERT (0);
396 break;
397
398#define _(N_KEY_U32) \
399 case N_KEY_U32: \
400 if (op == GET) \
401 clib_pipeline_run_3_stage \
402 (1, \
403 tm, \
404 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
405 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
406 test_vhash_get_mod_stage_##N_KEY_U32); \
407 else if (op == SET) \
408 clib_pipeline_run_3_stage \
409 (1, \
410 tm, \
411 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
412 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
413 test_vhash_set_mod_stage_##N_KEY_U32); \
414 else \
415 clib_pipeline_run_3_stage \
416 (1, \
417 tm, \
418 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
419 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
420 test_vhash_unset_mod_stage_##N_KEY_U32); \
421 break;
422
Dave Barachc3799992016-08-15 11:12:27 -0400423 _(1);
424 _(2);
425 _(3);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426
427#undef _
428
429#define _(N_KEY_U32) \
430 case N_KEY_U32: \
431 if (op == GET) \
432 clib_pipeline_run_4_stage \
433 (1, \
434 tm, \
435 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
436 test_vhash_hash_mix_mod_stage_##N_KEY_U32, \
437 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
438 test_vhash_get_mod_stage_##N_KEY_U32); \
439 else if (op == SET) \
440 clib_pipeline_run_4_stage \
441 (1, \
442 tm, \
443 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
444 test_vhash_hash_mix_mod_stage_##N_KEY_U32, \
445 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
446 test_vhash_set_mod_stage_##N_KEY_U32); \
447 else \
448 clib_pipeline_run_4_stage \
449 (1, \
450 tm, \
451 test_vhash_gather_keys_mod_stage_##N_KEY_U32, \
452 test_vhash_hash_mix_mod_stage_##N_KEY_U32, \
453 test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \
454 test_vhash_unset_mod_stage_##N_KEY_U32); \
455 break;
456
Dave Barachc3799992016-08-15 11:12:27 -0400457 _(4);
458 _(5);
459 _(6);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700460
461#undef _
462 }
463 }
464}
465
Dave Barachc3799992016-08-15 11:12:27 -0400466int
467test_vhash_main (unformat_input_t * input)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700468{
Dave Barachc3799992016-08-15 11:12:27 -0400469 clib_error_t *error = 0;
470 test_vhash_main_t _tm, *tm = &_tm;
471 vhash_t *vh = &tm->vhash;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700472 uword i, j;
473
474 memset (tm, 0, sizeof (tm[0]));
475 tm->n_iter = 100;
476 tm->seed = 1;
477 tm->n_keys = 1;
478 tm->n_key_u32 = 1;
479 tm->log2_size = 8;
480 tm->verbose = 0;
481
482 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
483 {
484 if (unformat (input, "iter %d", &tm->n_iter))
485 ;
486 else if (unformat (input, "seed %d", &tm->seed))
487 ;
488 else if (unformat (input, "n-keys %d", &tm->n_keys))
489 ;
490 else if (unformat (input, "log2-size %d", &tm->log2_size))
491 ;
492 else if (unformat (input, "key-words %d", &tm->n_key_u32))
493 ;
494 else if (unformat (input, "verbose %=", &tm->verbose, 1))
495 ;
496 else
497 {
498 error = clib_error_create ("unknown input `%U'\n",
499 format_unformat_error, input);
500 goto done;
501 }
502 }
503
504 if (tm->seed == 0)
505 tm->seed = random_default_seed ();
506
507 clib_warning ("iter %d seed %d n-keys %d log2-size %d key-words %d",
Dave Barachc3799992016-08-15 11:12:27 -0400508 tm->n_iter, tm->seed, tm->n_keys, tm->log2_size,
509 tm->n_key_u32);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700510
511 {
512 u32 seeds[3];
513 seeds[0] = seeds[1] = seeds[2] = 0xdeadbeef;
514 vhash_init (vh, tm->log2_size, tm->n_key_u32, seeds);
515 }
516
517 /* Choose unique keys. */
518 vec_resize (tm->keys, tm->n_keys * tm->n_key_u32);
519 vec_resize (tm->key_hash, tm->n_key_u32);
520 for (i = j = 0; i < vec_len (tm->keys); i++, j++)
521 {
522 j = j == tm->n_key_u32 ? 0 : j;
Dave Barachc3799992016-08-15 11:12:27 -0400523 do
524 {
525 tm->keys[i] = random_u32 (&tm->seed);
526 }
527 while (hash_get (tm->key_hash[j], tm->keys[i]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700528 hash_set (tm->key_hash[j], tm->keys[i], 0);
529 }
530
531 vec_resize (tm->results, tm->n_keys);
532 for (i = 0; i < vec_len (tm->results); i++)
533 {
Dave Barachc3799992016-08-15 11:12:27 -0400534 do
535 {
536 tm->results[i] = random_u32 (&tm->seed);
537 }
538 while (tm->results[i] == ~0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700539 }
540
Dave Barachc3799992016-08-15 11:12:27 -0400541 vec_resize_aligned (tm->vhash_get_results, tm->n_keys,
542 CLIB_CACHE_LINE_BYTES);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700543 vec_clone (tm->vhash_get_key_indices, tm->results);
544 for (i = 0; i < vec_len (tm->vhash_get_key_indices); i++)
545 tm->vhash_get_key_indices[i] = i;
546
547 {
Dave Barachc3799992016-08-15 11:12:27 -0400548 uword *is_set_bitmap = 0;
549 uword *to_set_bitmap = 0;
550 uword *to_unset_bitmap = 0;
551 u32 *to_set = 0, *to_unset = 0;
552 u32 *to_set_results = 0, *to_unset_results = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700553 u64 t[2];
554
555 for (i = 0; i < tm->n_iter; i++)
556 {
557 vec_reset_length (to_set);
558 vec_reset_length (to_unset);
559 vec_reset_length (to_set_results);
560 vec_reset_length (to_unset_results);
561
Dave Barachc3799992016-08-15 11:12:27 -0400562 do
563 {
564 to_set_bitmap = clib_bitmap_random (to_set_bitmap,
565 tm->n_keys, &tm->seed);
566 }
567 while (clib_bitmap_is_zero (to_set_bitmap));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700568 to_unset_bitmap = clib_bitmap_dup_and (to_set_bitmap, is_set_bitmap);
569 to_set_bitmap = clib_bitmap_andnot (to_set_bitmap, to_unset_bitmap);
570
Dave Barachc3799992016-08-15 11:12:27 -0400571 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700572 clib_bitmap_foreach (j, to_set_bitmap, ({
573 vec_add1 (to_set, j);
574 vec_add1 (to_set_results, tm->results[j]);
575 }));
Dave Barachc3799992016-08-15 11:12:27 -0400576 /* *INDENT-ON* */
577 /* *INDENT-OFF* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700578 clib_bitmap_foreach (j, to_unset_bitmap, ({
579 vec_add1 (to_unset, j);
580 vec_add1 (to_unset_results, 0xdeadbeef);
581 }));
Dave Barachc3799992016-08-15 11:12:27 -0400582 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700583
584 if (vec_len (to_set) > 0)
585 {
586 t[0] = clib_cpu_time_now ();
Dave Barachc3799992016-08-15 11:12:27 -0400587 test_vhash_op (tm, to_set, to_set_results, vec_len (to_set), SET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700588 t[1] = clib_cpu_time_now ();
589 tm->set_stats.n_clocks += t[1] - t[0];
590 tm->set_stats.n_vectors += vec_len (to_set);
591 tm->set_stats.n_calls += 1;
592 is_set_bitmap = clib_bitmap_or (is_set_bitmap, to_set_bitmap);
593 }
594
595 t[0] = clib_cpu_time_now ();
596 test_vhash_op (tm, tm->vhash_get_key_indices,
597 tm->vhash_get_results,
Dave Barachc3799992016-08-15 11:12:27 -0400598 vec_len (tm->vhash_get_key_indices), GET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700599 t[1] = clib_cpu_time_now ();
600 tm->get_stats.n_clocks += t[1] - t[0];
601 tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices);
602 tm->get_stats.n_calls += 1;
603
604 for (j = 0; j < vec_len (tm->vhash_get_results); j++)
605 {
606 u32 r0 = tm->vhash_get_results[j];
607 u32 r1 = tm->results[j];
608 if (clib_bitmap_get (is_set_bitmap, j))
609 {
610 if (r0 != r1)
611 os_panic ();
612 }
613 else
614 {
615 if (r0 != ~0)
616 os_panic ();
617 }
618 }
619
620 if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
621 os_panic ();
622
623 if (vec_len (to_unset) > 0)
624 {
625 t[0] = clib_cpu_time_now ();
626 test_vhash_op (tm, to_unset, to_unset_results,
Dave Barachc3799992016-08-15 11:12:27 -0400627 vec_len (to_unset), UNSET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700628 t[1] = clib_cpu_time_now ();
629 tm->unset_stats.n_clocks += t[1] - t[0];
630 tm->unset_stats.n_vectors += vec_len (to_unset);
631 tm->unset_stats.n_calls += 1;
Dave Barachc3799992016-08-15 11:12:27 -0400632 is_set_bitmap =
633 clib_bitmap_andnot (is_set_bitmap, to_unset_bitmap);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700634 }
635
636 t[0] = clib_cpu_time_now ();
637 test_vhash_op (tm, tm->vhash_get_key_indices,
638 tm->vhash_get_results,
Dave Barachc3799992016-08-15 11:12:27 -0400639 vec_len (tm->vhash_get_key_indices), GET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700640 t[1] = clib_cpu_time_now ();
641 tm->get_stats.n_clocks += t[1] - t[0];
642 tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices);
643 tm->get_stats.n_calls += 1;
644
645 for (j = 0; j < vec_len (tm->vhash_get_results); j++)
646 {
647 u32 r0 = tm->vhash_get_results[j];
648 u32 r1 = tm->results[j];
649 if (clib_bitmap_get (is_set_bitmap, j))
650 {
651 if (r0 != r1)
652 os_panic ();
653 }
654 else
655 {
656 if (r0 != ~0)
657 os_panic ();
658 }
659 }
660
661 if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
662 os_panic ();
663 }
664
665 vhash_resize (vh, tm->log2_size + 1);
666
667 test_vhash_op (tm, tm->vhash_get_key_indices,
668 tm->vhash_get_results,
Dave Barachc3799992016-08-15 11:12:27 -0400669 vec_len (tm->vhash_get_key_indices), GET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700670
671 for (j = 0; j < vec_len (tm->vhash_get_results); j++)
672 {
673 u32 r0 = tm->vhash_get_results[j];
674 u32 r1 = tm->results[j];
675 if (clib_bitmap_get (is_set_bitmap, j))
676 {
677 if (r0 != r1)
678 os_panic ();
679 }
680 else
681 {
682 if (r0 != ~0)
683 os_panic ();
684 }
685 }
686
687 if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap))
688 os_panic ();
689 }
690
691 {
692 clib_time_t ct;
693
694 clib_time_init (&ct);
695
696 clib_warning ("%.4e clocks/get %.4e gets/call %.4e gets/sec",
Dave Barachc3799992016-08-15 11:12:27 -0400697 (f64) tm->get_stats.n_clocks /
698 (f64) tm->get_stats.n_vectors,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699 (f64) tm->get_stats.n_vectors / (f64) tm->get_stats.n_calls,
Dave Barachc3799992016-08-15 11:12:27 -0400700 (f64) tm->get_stats.n_vectors /
701 (f64) (tm->get_stats.n_clocks * ct.seconds_per_clock));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700702 if (tm->set_stats.n_calls > 0)
703 clib_warning ("%.4e clocks/set %.4e sets/call %.4e sets/sec",
Dave Barachc3799992016-08-15 11:12:27 -0400704 (f64) tm->set_stats.n_clocks /
705 (f64) tm->set_stats.n_vectors,
706 (f64) tm->set_stats.n_vectors /
707 (f64) tm->set_stats.n_calls,
708 (f64) tm->set_stats.n_vectors /
709 (f64) (tm->set_stats.n_clocks * ct.seconds_per_clock));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700710 if (tm->unset_stats.n_calls > 0)
711 clib_warning ("%.4e clocks/unset %.4e unsets/call %.4e unsets/sec",
Dave Barachc3799992016-08-15 11:12:27 -0400712 (f64) tm->unset_stats.n_clocks /
713 (f64) tm->unset_stats.n_vectors,
714 (f64) tm->unset_stats.n_vectors /
715 (f64) tm->unset_stats.n_calls,
716 (f64) tm->unset_stats.n_vectors /
717 (f64) (tm->unset_stats.n_clocks * ct.seconds_per_clock));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718 }
719
Dave Barachc3799992016-08-15 11:12:27 -0400720done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700721 if (error)
722 clib_error_report (error);
723 return 0;
724}
725
726#endif /* CLIB_HAVE_VEC128 */
727
728#ifndef CLIB_HAVE_VEC128
Dave Barachc3799992016-08-15 11:12:27 -0400729int
730test_vhash_main (unformat_input_t * input)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700731{
732 clib_error ("compiled without vector support");
733 return 0;
734}
735#endif
736
737#ifdef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -0400738int
739main (int argc, char *argv[])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700740{
741 unformat_input_t i;
742 int r;
743
Damjan Marion4dffd1c2018-09-03 12:30:36 +0200744 clib_mem_init (0, 64ULL << 20);
745
Ed Warnickecb9cada2015-12-08 15:45:58 -0700746 unformat_init_command_line (&i, argv);
747 r = test_vhash_main (&i);
748 unformat_free (&i);
749 return r;
750}
751#endif
Dave Barachc3799992016-08-15 11:12:27 -0400752
753/*
754 * fd.io coding-style-patch-verification: ON
755 *
756 * Local Variables:
757 * eval: (c-set-style "gnu")
758 * End:
759 */