From cb9cadad578297ffd78fa8a33670bdf1ab669e7e Mon Sep 17 00:00:00 2001 From: Ed Warnicke Date: Tue, 8 Dec 2015 15:45:58 -0700 Subject: Initial commit of vpp code. Change-Id: Ib246f1fbfce93274020ee93ce461e3d8bd8b9f17 Signed-off-by: Ed Warnicke --- vppinfra/vppinfra/test_vhash.c | 736 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 736 insertions(+) create mode 100644 vppinfra/vppinfra/test_vhash.c (limited to 'vppinfra/vppinfra/test_vhash.c') diff --git a/vppinfra/vppinfra/test_vhash.c b/vppinfra/vppinfra/test_vhash.c new file mode 100644 index 00000000000..8316cf76d2b --- /dev/null +++ b/vppinfra/vppinfra/test_vhash.c @@ -0,0 +1,736 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + Copyright (c) 2010 Eliot Dresselhaus + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#if 0 +#ifdef __OPTIMIZE__ +#undef CLIB_DEBUG +#endif +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef CLIB_HAVE_VEC128 + +typedef struct { + u32 n_iter; + u32 seed; + u32 verbose; + u32 n_keys; + u32 log2_size; + u32 n_key_u32; + + u32 n_vectors_div_4; + u32 n_vectors_mod_4; + + u32 * keys; + u32 * results; + + u32 * vhash_get_key_indices; + u32 * vhash_get_results; + + u32 * vhash_key_indices; + u32 * vhash_results; + + vhash_t vhash; + + uword ** key_hash; + + struct { + u64 n_clocks; + u64 n_vectors; + u64 n_calls; + } get_stats, set_stats, unset_stats; +} test_vhash_main_t; + +always_inline u32 +test_vhash_key_gather (void * _tm, u32 vi, u32 wi, u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + ASSERT (n_key_u32s == tm->n_key_u32); + ASSERT (wi < n_key_u32s); + vi = vec_elt (tm->vhash_key_indices, vi); + return vec_elt (tm->keys, vi * n_key_u32s + wi); +} + +always_inline u32x4 +test_vhash_4key_gather (void * _tm, u32 vi, u32 wi, u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + u32 * p; + u32x4_union_t x; + + ASSERT (n_key_u32s == tm->n_key_u32); + ASSERT (wi < n_key_u32s); + + p = vec_elt_at_index (tm->vhash_key_indices, vi + 0); + x.as_u32[0] = tm->keys[p[0] * n_key_u32s + wi]; + x.as_u32[1] = tm->keys[p[1] * n_key_u32s + wi]; + x.as_u32[2] = tm->keys[p[2] * n_key_u32s + wi]; + x.as_u32[3] = tm->keys[p[3] * n_key_u32s + wi]; + return x.as_u32x4; +} + +always_inline u32 +test_vhash_get_result (void * _tm, + u32 vector_index, + u32 result_index, + u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + u32 * p = vec_elt_at_index (tm->vhash_results, vector_index); + p[0] = result_index; + return result_index; +} + +always_inline u32x4 +test_vhash_get_4result (void * _tm, + u32 vector_index, + u32x4 results, + u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + u32 * p = vec_elt_at_index (tm->vhash_results, vector_index); + *(u32x4 *)p = results; + return results; +} + +always_inline u32 +test_vhash_set_result (void * _tm, + u32 vector_index, + u32 old_result, + u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + u32 * p = vec_elt_at_index (tm->vhash_results, vector_index); + u32 new_result = p[0]; + p[0] = old_result; + return new_result; +} + +always_inline u32 +test_vhash_unset_result (void * _tm, u32 i, u32 old_result, u32 n_key_u32s) +{ + test_vhash_main_t * tm = _tm; + u32 * p = vec_elt_at_index (tm->vhash_results, i); + p[0] = old_result; + return 0; +} + +#define _(N_KEY_U32) \ + always_inline u32 \ + test_vhash_key_gather_##N_KEY_U32 (void * _tm, u32 vi, u32 i) \ + { return test_vhash_key_gather (_tm, vi, i, N_KEY_U32); } \ + \ + always_inline u32x4 \ + test_vhash_key_gather_4_##N_KEY_U32 (void * _tm, u32 vi, u32 i) \ + { return test_vhash_4key_gather (_tm, vi, i, N_KEY_U32); } \ + \ + clib_pipeline_stage \ + (test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_gather_4key_stage \ + (&tm->vhash, \ + /* vector_index */ i, \ + test_vhash_key_gather_4_##N_KEY_U32, \ + tm, \ + N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_gather_key_stage \ + (&tm->vhash, \ + /* vector_index */ tm->n_vectors_div_4, \ + /* n_vectors */ tm->n_vectors_mod_4, \ + test_vhash_key_gather_##N_KEY_U32, \ + tm, \ + N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage \ + (test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_finalize_stage (&tm->vhash, i, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_finalize_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage \ + (test_vhash_get_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_get_4_stage (&tm->vhash, \ + /* vector_index */ i, \ + test_vhash_get_4result, \ + tm, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_get_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_get_stage (&tm->vhash, \ + /* vector_index */ tm->n_vectors_div_4, \ + /* n_vectors */ tm->n_vectors_mod_4, \ + test_vhash_get_result, \ + tm, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage \ + (test_vhash_set_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_set_stage (&tm->vhash, \ + /* vector_index */ i, \ + /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32), \ + test_vhash_set_result, \ + tm, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_set_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_set_stage (&tm->vhash, \ + /* vector_index */ tm->n_vectors_div_4, \ + /* n_vectors */ tm->n_vectors_mod_4, \ + test_vhash_set_result, \ + tm, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage \ + (test_vhash_unset_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_unset_stage (&tm->vhash, \ + /* vector_index */ i, \ + /* n_vectors */ VECTOR_WORD_TYPE_LEN (u32), \ + test_vhash_unset_result, \ + tm, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_unset_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_unset_stage (&tm->vhash, \ + /* vector_index */ tm->n_vectors_div_4, \ + /* n_vectors */ tm->n_vectors_mod_4, \ + test_vhash_unset_result, \ + tm, N_KEY_U32); \ + }) + +_ (1); +_ (2); +_ (3); +_ (4); +_ (5); +_ (6); + +#undef _ + +#define _(N_KEY_U32) \ + clib_pipeline_stage \ + (test_vhash_hash_mix_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_mix_stage (&tm->vhash, i, N_KEY_U32); \ + }) \ + \ + clib_pipeline_stage_no_inline \ + (test_vhash_hash_mix_mod_stage_##N_KEY_U32, \ + test_vhash_main_t *, tm, i, \ + { \ + vhash_mix_stage (&tm->vhash, tm->n_vectors_div_4, N_KEY_U32); \ + }) + +_ (4); +_ (5); +_ (6); + +#undef _ + +typedef enum { + GET, SET, UNSET, +} test_vhash_op_t; + +static void +test_vhash_op (test_vhash_main_t * tm, + u32 * key_indices, + u32 * results, + uword n_keys, + test_vhash_op_t op) +{ + vhash_validate_sizes (&tm->vhash, tm->n_key_u32, n_keys); + + tm->vhash_results = results; + tm->vhash_key_indices = key_indices; + tm->n_vectors_div_4 = n_keys / 4; + tm->n_vectors_mod_4 = n_keys % 4; + + if (tm->n_vectors_div_4 > 0) + { + switch (tm->n_key_u32) + { + default: + ASSERT (0); + break; + +#define _(N_KEY_U32) \ + case N_KEY_U32: \ + if (op == GET) \ + clib_pipeline_run_3_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_get_stage_##N_KEY_U32); \ + else if (op == SET) \ + clib_pipeline_run_3_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_set_stage_##N_KEY_U32); \ + else \ + clib_pipeline_run_3_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_unset_stage_##N_KEY_U32); \ + break; + + _ (1); + _ (2); + _ (3); + +#undef _ + +#define _(N_KEY_U32) \ + case N_KEY_U32: \ + if (op == GET) \ + clib_pipeline_run_4_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_mix_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_get_stage_##N_KEY_U32); \ + else if (op == SET) \ + clib_pipeline_run_4_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_mix_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_set_stage_##N_KEY_U32); \ + else \ + clib_pipeline_run_4_stage \ + (tm->n_vectors_div_4, \ + tm, \ + test_vhash_gather_keys_stage_##N_KEY_U32, \ + test_vhash_hash_mix_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_stage_##N_KEY_U32, \ + test_vhash_unset_stage_##N_KEY_U32); \ + break; + + _ (4); + _ (5); + _ (6); + +#undef _ + } + } + + + if (tm->n_vectors_mod_4 > 0) + { + switch (tm->n_key_u32) + { + default: + ASSERT (0); + break; + +#define _(N_KEY_U32) \ + case N_KEY_U32: \ + if (op == GET) \ + clib_pipeline_run_3_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_get_mod_stage_##N_KEY_U32); \ + else if (op == SET) \ + clib_pipeline_run_3_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_set_mod_stage_##N_KEY_U32); \ + else \ + clib_pipeline_run_3_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_unset_mod_stage_##N_KEY_U32); \ + break; + + _ (1); + _ (2); + _ (3); + +#undef _ + +#define _(N_KEY_U32) \ + case N_KEY_U32: \ + if (op == GET) \ + clib_pipeline_run_4_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_mix_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_get_mod_stage_##N_KEY_U32); \ + else if (op == SET) \ + clib_pipeline_run_4_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_mix_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_set_mod_stage_##N_KEY_U32); \ + else \ + clib_pipeline_run_4_stage \ + (1, \ + tm, \ + test_vhash_gather_keys_mod_stage_##N_KEY_U32, \ + test_vhash_hash_mix_mod_stage_##N_KEY_U32, \ + test_vhash_hash_finalize_mod_stage_##N_KEY_U32, \ + test_vhash_unset_mod_stage_##N_KEY_U32); \ + break; + + _ (4); + _ (5); + _ (6); + +#undef _ + } + } +} + +int test_vhash_main (unformat_input_t * input) +{ + clib_error_t * error = 0; + test_vhash_main_t _tm, * tm = &_tm; + vhash_t * vh = &tm->vhash; + uword i, j; + + memset (tm, 0, sizeof (tm[0])); + tm->n_iter = 100; + tm->seed = 1; + tm->n_keys = 1; + tm->n_key_u32 = 1; + tm->log2_size = 8; + tm->verbose = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "iter %d", &tm->n_iter)) + ; + else if (unformat (input, "seed %d", &tm->seed)) + ; + else if (unformat (input, "n-keys %d", &tm->n_keys)) + ; + else if (unformat (input, "log2-size %d", &tm->log2_size)) + ; + else if (unformat (input, "key-words %d", &tm->n_key_u32)) + ; + else if (unformat (input, "verbose %=", &tm->verbose, 1)) + ; + else + { + error = clib_error_create ("unknown input `%U'\n", + format_unformat_error, input); + goto done; + } + } + + if (tm->seed == 0) + tm->seed = random_default_seed (); + + clib_warning ("iter %d seed %d n-keys %d log2-size %d key-words %d", + tm->n_iter, tm->seed, tm->n_keys, tm->log2_size, tm->n_key_u32); + + { + u32 seeds[3]; + seeds[0] = seeds[1] = seeds[2] = 0xdeadbeef; + vhash_init (vh, tm->log2_size, tm->n_key_u32, seeds); + } + + /* Choose unique keys. */ + vec_resize (tm->keys, tm->n_keys * tm->n_key_u32); + vec_resize (tm->key_hash, tm->n_key_u32); + for (i = j = 0; i < vec_len (tm->keys); i++, j++) + { + j = j == tm->n_key_u32 ? 0 : j; + do { + tm->keys[i] = random_u32 (&tm->seed); + } while (hash_get (tm->key_hash[j], tm->keys[i])); + hash_set (tm->key_hash[j], tm->keys[i], 0); + } + + vec_resize (tm->results, tm->n_keys); + for (i = 0; i < vec_len (tm->results); i++) + { + do { + tm->results[i] = random_u32 (&tm->seed); + } while (tm->results[i] == ~0); + } + + vec_resize_aligned (tm->vhash_get_results, tm->n_keys, CLIB_CACHE_LINE_BYTES); + vec_clone (tm->vhash_get_key_indices, tm->results); + for (i = 0; i < vec_len (tm->vhash_get_key_indices); i++) + tm->vhash_get_key_indices[i] = i; + + { + uword * is_set_bitmap = 0; + uword * to_set_bitmap = 0; + uword * to_unset_bitmap = 0; + u32 * to_set = 0, * to_unset = 0; + u32 * to_set_results = 0, * to_unset_results = 0; + u64 t[2]; + + for (i = 0; i < tm->n_iter; i++) + { + vec_reset_length (to_set); + vec_reset_length (to_unset); + vec_reset_length (to_set_results); + vec_reset_length (to_unset_results); + + do { + to_set_bitmap = clib_bitmap_random (to_set_bitmap, + tm->n_keys, &tm->seed); + } while (clib_bitmap_is_zero (to_set_bitmap)); + to_unset_bitmap = clib_bitmap_dup_and (to_set_bitmap, is_set_bitmap); + to_set_bitmap = clib_bitmap_andnot (to_set_bitmap, to_unset_bitmap); + + clib_bitmap_foreach (j, to_set_bitmap, ({ + vec_add1 (to_set, j); + vec_add1 (to_set_results, tm->results[j]); + })); + clib_bitmap_foreach (j, to_unset_bitmap, ({ + vec_add1 (to_unset, j); + vec_add1 (to_unset_results, 0xdeadbeef); + })); + + if (vec_len (to_set) > 0) + { + t[0] = clib_cpu_time_now (); + test_vhash_op (tm, to_set, to_set_results, + vec_len (to_set), + SET); + t[1] = clib_cpu_time_now (); + tm->set_stats.n_clocks += t[1] - t[0]; + tm->set_stats.n_vectors += vec_len (to_set); + tm->set_stats.n_calls += 1; + is_set_bitmap = clib_bitmap_or (is_set_bitmap, to_set_bitmap); + } + + t[0] = clib_cpu_time_now (); + test_vhash_op (tm, tm->vhash_get_key_indices, + tm->vhash_get_results, + vec_len (tm->vhash_get_key_indices), + GET); + t[1] = clib_cpu_time_now (); + tm->get_stats.n_clocks += t[1] - t[0]; + tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices); + tm->get_stats.n_calls += 1; + + for (j = 0; j < vec_len (tm->vhash_get_results); j++) + { + u32 r0 = tm->vhash_get_results[j]; + u32 r1 = tm->results[j]; + if (clib_bitmap_get (is_set_bitmap, j)) + { + if (r0 != r1) + os_panic (); + } + else + { + if (r0 != ~0) + os_panic (); + } + } + + if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap)) + os_panic (); + + if (vec_len (to_unset) > 0) + { + t[0] = clib_cpu_time_now (); + test_vhash_op (tm, to_unset, to_unset_results, + vec_len (to_unset), + UNSET); + t[1] = clib_cpu_time_now (); + tm->unset_stats.n_clocks += t[1] - t[0]; + tm->unset_stats.n_vectors += vec_len (to_unset); + tm->unset_stats.n_calls += 1; + is_set_bitmap = clib_bitmap_andnot (is_set_bitmap, to_unset_bitmap); + } + + t[0] = clib_cpu_time_now (); + test_vhash_op (tm, tm->vhash_get_key_indices, + tm->vhash_get_results, + vec_len (tm->vhash_get_key_indices), + GET); + t[1] = clib_cpu_time_now (); + tm->get_stats.n_clocks += t[1] - t[0]; + tm->get_stats.n_vectors += vec_len (tm->vhash_get_key_indices); + tm->get_stats.n_calls += 1; + + for (j = 0; j < vec_len (tm->vhash_get_results); j++) + { + u32 r0 = tm->vhash_get_results[j]; + u32 r1 = tm->results[j]; + if (clib_bitmap_get (is_set_bitmap, j)) + { + if (r0 != r1) + os_panic (); + } + else + { + if (r0 != ~0) + os_panic (); + } + } + + if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap)) + os_panic (); + } + + vhash_resize (vh, tm->log2_size + 1); + + test_vhash_op (tm, tm->vhash_get_key_indices, + tm->vhash_get_results, + vec_len (tm->vhash_get_key_indices), + GET); + + for (j = 0; j < vec_len (tm->vhash_get_results); j++) + { + u32 r0 = tm->vhash_get_results[j]; + u32 r1 = tm->results[j]; + if (clib_bitmap_get (is_set_bitmap, j)) + { + if (r0 != r1) + os_panic (); + } + else + { + if (r0 != ~0) + os_panic (); + } + } + + if (vh->n_elts != clib_bitmap_count_set_bits (is_set_bitmap)) + os_panic (); + } + + { + clib_time_t ct; + + clib_time_init (&ct); + + clib_warning ("%.4e clocks/get %.4e gets/call %.4e gets/sec", + (f64) tm->get_stats.n_clocks / (f64) tm->get_stats.n_vectors, + (f64) tm->get_stats.n_vectors / (f64) tm->get_stats.n_calls, + (f64) tm->get_stats.n_vectors / (f64) (tm->get_stats.n_clocks * ct.seconds_per_clock)); + if (tm->set_stats.n_calls > 0) + clib_warning ("%.4e clocks/set %.4e sets/call %.4e sets/sec", + (f64) tm->set_stats.n_clocks / (f64) tm->set_stats.n_vectors, + (f64) tm->set_stats.n_vectors / (f64) tm->set_stats.n_calls, + (f64) tm->set_stats.n_vectors / (f64) (tm->set_stats.n_clocks * ct.seconds_per_clock)); + if (tm->unset_stats.n_calls > 0) + clib_warning ("%.4e clocks/unset %.4e unsets/call %.4e unsets/sec", + (f64) tm->unset_stats.n_clocks / (f64) tm->unset_stats.n_vectors, + (f64) tm->unset_stats.n_vectors / (f64) tm->unset_stats.n_calls, + (f64) tm->unset_stats.n_vectors / (f64) (tm->unset_stats.n_clocks * ct.seconds_per_clock)); + } + + done: + if (error) + clib_error_report (error); + return 0; +} + +#endif /* CLIB_HAVE_VEC128 */ + +#ifndef CLIB_HAVE_VEC128 +int test_vhash_main (unformat_input_t * input) +{ + clib_error ("compiled without vector support"); + return 0; +} +#endif + +#ifdef CLIB_UNIX +int main (int argc, char * argv []) +{ + unformat_input_t i; + int r; + + unformat_init_command_line (&i, argv); + r = test_vhash_main (&i); + unformat_free (&i); + return r; +} +#endif -- cgit 1.2.3-korg