dpdk/app/test/test_lpm6_perf.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2010-2014 Intel Corporation
   3 */
   4
   5#include <stdio.h>
   6#include <stdint.h>
   7#include <stdlib.h>
   8#include <string.h>
   9
  10#include <rte_cycles.h>
  11#include <rte_random.h>
  12#include <rte_memory.h>
  13#include <rte_lpm6.h>
  14
  15#include "test.h"
  16#include "test_lpm6_data.h"
  17
  18#define TEST_LPM_ASSERT(cond) do {                                            \
  19        if (!(cond)) {                                                        \
  20                printf("Error at line %d: \n", __LINE__);                     \
  21                return -1;                                                    \
  22        }                                                                     \
  23} while(0)
  24
  25#define ITERATIONS (1 << 10)
  26#define BATCH_SIZE 100000
  27#define NUMBER_TBL8S                                           (1 << 16)
  28
  29static void
  30print_route_distribution(const struct rules_tbl_entry *table, uint32_t n)
  31{
  32        unsigned i, j;
  33
  34        printf("Route distribution per prefix width: \n");
  35        printf("DEPTH    QUANTITY (PERCENT)\n");
  36        printf("--------------------------- \n");
  37
  38        /* Count depths. */
  39        for(i = 1; i <= 128; i++) {
  40                unsigned depth_counter = 0;
  41                double percent_hits;
  42
  43                for (j = 0; j < n; j++)
  44                        if (table[j].depth == (uint8_t) i)
  45                                depth_counter++;
  46
  47                percent_hits = ((double)depth_counter)/((double)n) * 100;
  48                printf("%.2u%15u (%.2f)\n", i, depth_counter, percent_hits);
  49        }
  50        printf("\n");
  51}
  52
  53static int
  54test_lpm6_perf(void)
  55{
  56        struct rte_lpm6 *lpm = NULL;
  57        struct rte_lpm6_config config;
  58        uint64_t begin, total_time;
  59        unsigned i, j;
  60        uint32_t next_hop_add = 0xAA, next_hop_return = 0;
  61        int status = 0;
  62        int64_t count = 0;
  63
  64        config.max_rules = 1000000;
  65        config.number_tbl8s = NUMBER_TBL8S;
  66        config.flags = 0;
  67
  68        rte_srand(rte_rdtsc());
  69
  70        printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
  71
  72        print_route_distribution(large_route_table, (uint32_t) NUM_ROUTE_ENTRIES);
  73
  74        /* Only generate IPv6 address of each item in large IPS table,
  75         * here next_hop is not needed.
  76         */
  77        generate_large_ips_table(0);
  78
  79        lpm = rte_lpm6_create(__func__, SOCKET_ID_ANY, &config);
  80        TEST_LPM_ASSERT(lpm != NULL);
  81
  82        /* Measure add. */
  83        begin = rte_rdtsc();
  84
  85        for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
  86                if (rte_lpm6_add(lpm, large_route_table[i].ip,
  87                                large_route_table[i].depth, next_hop_add) == 0)
  88                        status++;
  89        }
  90        /* End Timer. */
  91        total_time = rte_rdtsc() - begin;
  92
  93        printf("Unique added entries = %d\n", status);
  94        printf("Average LPM Add: %g cycles\n",
  95                        (double)total_time / NUM_ROUTE_ENTRIES);
  96
  97        /* Measure single Lookup */
  98        total_time = 0;
  99        count = 0;
 100
 101        for (i = 0; i < ITERATIONS; i ++) {
 102                begin = rte_rdtsc();
 103
 104                for (j = 0; j < NUM_IPS_ENTRIES; j ++) {
 105                        if (rte_lpm6_lookup(lpm, large_ips_table[j].ip,
 106                                        &next_hop_return) != 0)
 107                                count++;
 108                }
 109
 110                total_time += rte_rdtsc() - begin;
 111
 112        }
 113        printf("Average LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
 114                        (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
 115                        (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
 116
 117        /* Measure bulk Lookup */
 118        total_time = 0;
 119        count = 0;
 120
 121        uint8_t ip_batch[NUM_IPS_ENTRIES][16];
 122        int32_t next_hops[NUM_IPS_ENTRIES];
 123
 124        for (i = 0; i < NUM_IPS_ENTRIES; i++)
 125                memcpy(ip_batch[i], large_ips_table[i].ip, 16);
 126
 127        for (i = 0; i < ITERATIONS; i ++) {
 128
 129                /* Lookup per batch */
 130                begin = rte_rdtsc();
 131                rte_lpm6_lookup_bulk_func(lpm, ip_batch, next_hops, NUM_IPS_ENTRIES);
 132                total_time += rte_rdtsc() - begin;
 133
 134                for (j = 0; j < NUM_IPS_ENTRIES; j++)
 135                        if (next_hops[j] < 0)
 136                                count++;
 137        }
 138        printf("BULK LPM Lookup: %.1f cycles (fails = %.1f%%)\n",
 139                        (double)total_time / ((double)ITERATIONS * BATCH_SIZE),
 140                        (count * 100.0) / (double)(ITERATIONS * BATCH_SIZE));
 141
 142        /* Delete */
 143        status = 0;
 144        begin = rte_rdtsc();
 145
 146        for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
 147                /* rte_lpm_delete(lpm, ip, depth) */
 148                status += rte_lpm6_delete(lpm, large_route_table[i].ip,
 149                                large_route_table[i].depth);
 150        }
 151
 152        total_time += rte_rdtsc() - begin;
 153
 154        printf("Average LPM Delete: %g cycles\n",
 155                        (double)total_time / NUM_ROUTE_ENTRIES);
 156
 157        rte_lpm6_delete_all(lpm);
 158        rte_lpm6_free(lpm);
 159
 160        return 0;
 161}
 162
 163REGISTER_TEST_COMMAND(lpm6_perf_autotest, test_lpm6_perf);
 164