Re: [PATCH v4 3/4] Add autotests for RIB library
From: Bruce Richardson <hidden>
Date: 2018-06-29 15:31:35
On Fri, Apr 27, 2018 at 01:03:33AM +0300, Medvedkin Vladimir wrote:
Signed-off-by: Medvedkin Vladimir <redacted> --- test/test/Makefile | 5 + test/test/meson.build | 8 + test/test/test_rib.c | 308 +++++++++++++++++++++++++++++++++++++++ test/test/test_rib_generate_rt.c | 297 +++++++++++++++++++++++++++++++++++++ test/test/test_rib_generate_rt.h | 38 +++++ test/test/test_rib_lpm_comp.c | 189 ++++++++++++++++++++++++ test/test/test_rib_perf.c | 145 ++++++++++++++++++ 7 files changed, 990 insertions(+) create mode 100644 test/test/test_rib.c create mode 100644 test/test/test_rib_generate_rt.c create mode 100644 test/test/test_rib_generate_rt.h create mode 100644 test/test/test_rib_lpm_comp.c create mode 100644 test/test/test_rib_perf.c
<snip>
quoted hunk ↗ jump to hunk
diff --git a/test/test/test_rib_perf.c b/test/test/test_rib_perf.c new file mode 100644 index 0000000..42fbd1e --- /dev/null +++ b/test/test/test_rib_perf.c@@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com> + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + +#include <rte_cycles.h> +#include <rte_random.h> +#include <rte_branch_prediction.h> +#include <rte_ip.h> +#include <rte_malloc.h> +#include <rte_rib.h> +#include <rte_dir24_8.h> + +#include "test.h" +#include "test_xmmt_ops.h" +#include "test_rib_generate_rt.h" + +#define TEST_RIB_ASSERT(cond) do { \ + if (!(cond)) { \ + printf("Error at line %d:\n", __LINE__); \ + return -1; \ + } \ +} while (0) + +#define ITERATIONS (1 << 15) +#define BATCH_SIZE (1 << 12) +#define BULK_SIZE 32 + +#define NH_MSK(nh_sz) ((1ULL << ((1 << (3 + nh_sz)) - 1)) - 1) + +static int +test_rib_perf(void) +{ + struct rte_rib *rib = NULL; + struct rte_rib_conf conf; + struct route_rule *rt; + uint64_t begin, total_time; + uint64_t next_hop_add; + uint64_t default_nh = 0; + int64_t count = 0; + unsigned int i, j; + int status = 0; + int ret, nh_bits, nr_tbl8; + uint32_t num_routes; + + conf.max_nodes = 3000000; + conf.node_sz = sizeof(struct rte_rib_node); + conf.type = RTE_RIB_DIR24_8; + conf.fib_conf.dir24_8.def_nh = default_nh; + conf.fib_conf.dir24_8.nh_sz = RTE_DIR24_8_8B;
It's good that you are taking the worst-case to show the perf, but it means that the library comes out a bit slower than LPM in the autotest. How about running the same test cases for multiple data sizes, 8, 4, 2?
+
+ rte_srand(rte_rdtsc());
+
+ nh_bits = RTE_MIN(((1 << (3 + conf.fib_conf.dir24_8.nh_sz)) - 1), 24);
+ nr_tbl8 = RTE_MIN(((1 << nh_bits) - 1), 131071);
+ conf.fib_conf.dir24_8.num_tbl8 = nr_tbl8;
+ num_routes = 1200000;
+
+ rt = rte_zmalloc("struct route_rule *", sizeof(struct route_rule) *
+ num_routes, 0);
+ TEST_RIB_ASSERT(rt != NULL);
+
+ num_routes = generate_large_route_rule_table(num_routes, rt);
+ TEST_RIB_ASSERT(num_routes != 0);
+
+ printf("No. routes = %u\n", (unsigned int) num_routes);
+
+ shuffle_rt(rt, num_routes);
+
+ print_route_distribution(rt, (uint32_t) num_routes);
+
+ rib = rte_rib_create(__func__, SOCKET_ID_ANY, &conf);
+ TEST_RIB_ASSERT(rib != NULL);
+
+ /* Measue add. */
+ begin = rte_rdtsc();
+
+ for (i = 0; i < num_routes; i++) {
+ do {
+ next_hop_add = rte_rand() & NH_MSK(conf.fib_conf.dir24_8.nh_sz);
+ } while (next_hop_add == default_nh);
+
+ ret = rte_rib_add(rib, rt[i].ip, rt[i].depth, next_hop_add);
+ if ((ret == 0))
+ status++;
+ }
+
+ total_time = rte_rdtsc() - begin;
+
+ printf("Unique added entries = %d\n", status);
+ printf("Average RIB Add: %g cycles\n",
+ (double)total_time / num_routes);
+
+ /* Measure bulk Lookup */
+ total_time = 0;
+ count = 0;
+ for (i = 0; i < ITERATIONS; i++) {
+ static uint32_t ip_batch[BATCH_SIZE];
+ uint64_t next_hops[BULK_SIZE];
+
+ /* Create array of random IP addresses */
+ for (j = 0; j < BATCH_SIZE; j++)
+ ip_batch[j] = rte_rand();
+
+ /* Lookup per batch */
+ begin = rte_rdtsc();
+ for (j = 0; j < BATCH_SIZE; j += BULK_SIZE)
+ rte_rib_fib_lookup_bulk(rib, &ip_batch[j], next_hops,
+ BULK_SIZE);
+
+ total_time += rte_rdtsc() - begin;
+ for (j = 0; j < BULK_SIZE; j++) {
+ if (next_hops[j] == default_nh)
+ count++;
+ }
+ }
+ printf("BULK RIB Lookup: %.1f cycles (fails = %.1f%%)\n",
+ (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
+ (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
+
+ /* Delete */
+ status = 0;
+ begin = rte_rdtsc();
+
+ for (i = 0; i < num_routes; i++) {
+ ret = rte_rib_delete(rib, rt[i].ip, rt[i].depth);
+ if (ret == 0)
+ status++;
+ }
+
+ total_time = rte_rdtsc() - begin;
+
+ printf("Average RIB Delete: %g cycles\n",
+ (double)total_time / num_routes);
+
+ rte_rib_free(rib);
+ rte_free(rt);
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(rib_perf_autotest, test_rib_perf);
--
1.8.3.1