-/* TEST test15
- *
- * Lookup performance test using Mae West Routing Table
- */
-static inline uint32_t
-depth_to_mask(uint8_t depth) {
- return (int)0x80000000 >> (depth - 1);
-}
-
-static uint32_t
-rule_table_check_for_duplicates(const struct route_rule *table, uint32_t n){
- unsigned i, j, count;
-
- count = 0;
- for (i = 0; i < (n - 1); i++) {
- uint8_t depth1 = table[i].depth;
- uint32_t ip1_masked = table[i].ip & depth_to_mask(depth1);
-
- for (j = (i + 1); j <n; j ++) {
- uint8_t depth2 = table[j].depth;
- uint32_t ip2_masked = table[j].ip &
- depth_to_mask(depth2);
-
- if ((depth1 == depth2) && (ip1_masked == ip2_masked)){
- printf("Rule %u is a duplicate of rule %u\n",
- j, i);
- count ++;
- }
- }
- }
-
- return count;
-}
-
-static int32_t
-rule_table_characterisation(const struct route_rule *table, uint32_t n){
- unsigned i, j;
-
- printf("DEPTH QUANTITY (PERCENT)\n");
- printf("--------------------------------- \n");
- /* Count depths. */
- for(i = 1; i <= 32; i++) {
- unsigned depth_counter = 0;
- double percent_hits;
-
- for (j = 0; j < n; j++) {
- if (table[j].depth == (uint8_t) i)
- depth_counter++;
- }
-
- percent_hits = ((double)depth_counter)/((double)n) * 100;
-
- printf("%u - %5u (%.2f)\n",
- i, depth_counter, percent_hits);
- }
-
- return 0;
-}
-
-static inline uint64_t
-div64(uint64_t dividend, uint64_t divisor)
-{
- return ((2 * dividend) + divisor) / (2 * divisor);
-}
-
-int32_t
-test15(void)
-{
- struct rte_lpm *lpm = NULL;
- uint64_t begin, end, total_time, lpm_used_entries = 0;
- unsigned avg_ticks, i, j;
- uint8_t next_hop_add = 0, next_hop_return = 0;
- int32_t status = 0;
-
- printf("Using Mae West routing table from www.oiforum.com\n");
- printf("No. routes = %u\n", (unsigned) NUM_ROUTE_ENTRIES);
- printf("No. duplicate routes = %u\n\n", (unsigned)
- rule_table_check_for_duplicates(mae_west_tbl, NUM_ROUTE_ENTRIES));
- printf("Route distribution per prefix width: \n");
- rule_table_characterisation(mae_west_tbl,
- (uint32_t) NUM_ROUTE_ENTRIES);
- printf("\n");
-
- lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, 1000000,
- RTE_LPM_MEMZONE);
- TEST_LPM_ASSERT(lpm != NULL);
-
- next_hop_add = 1;
-
- /* Add */
- /* Begin Timer. */
- begin = rte_rdtsc();
-
- for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
- /* rte_lpm_add(lpm, ip, depth, next_hop_add) */
- status += rte_lpm_add(lpm, mae_west_tbl[i].ip,
- mae_west_tbl[i].depth, next_hop_add);
- }
- /* End Timer. */
- end = rte_rdtsc();
-
- TEST_LPM_ASSERT(status == 0);
-
- /* Calculate average cycles per add. */
- avg_ticks = (uint32_t) div64((end - begin),
- (uint64_t) NUM_ROUTE_ENTRIES);
-
- uint64_t cache_line_counter = 0;
- uint64_t count = 0;
-
- /* Obtain add statistics. */
- for (i = 0; i < RTE_LPM_TBL24_NUM_ENTRIES; i++) {
- if (lpm->tbl24[i].valid)
- lpm_used_entries++;
-
- if (i % 32 == 0){
- if (count < lpm_used_entries) {
- cache_line_counter++;
- count = lpm_used_entries;
- }
- }
- }
-
- printf("Number of table 24 entries = %u\n",
- (unsigned) RTE_LPM_TBL24_NUM_ENTRIES);
- printf("Used table 24 entries = %u\n",
- (unsigned) lpm_used_entries);
- printf("Percentage of table 24 entries used = %u\n",
- (unsigned) div64((lpm_used_entries * 100) ,
- RTE_LPM_TBL24_NUM_ENTRIES));
- printf("64 byte Cache entries used = %u \n",
- (unsigned) cache_line_counter);
- printf("Cache Required = %u bytes\n\n",
- (unsigned) cache_line_counter * 64);
-
- printf("Average LPM Add: %u cycles\n", avg_ticks);
-
- /* Lookup */
-
- /* Choose random seed. */
- rte_srand(0);
- total_time = 0;
- status = 0;
- for (i = 0; i < (ITERATIONS / BATCH_SIZE); i ++) {
- static uint32_t ip_batch[BATCH_SIZE];
- uint64_t begin_batch, end_batch;
-
- /* Generate a batch of random numbers */
- for (j = 0; j < BATCH_SIZE; j ++) {
- ip_batch[j] = rte_rand();
- }
-
- /* Lookup per batch */
- begin_batch = rte_rdtsc();
-
- for (j = 0; j < BATCH_SIZE; j ++) {
- status += rte_lpm_lookup(lpm, ip_batch[j],
- &next_hop_return);
- }
-
- end_batch = rte_rdtsc();
- printf("status = %d\r", next_hop_return);
- TEST_LPM_ASSERT(status < 1);
-
- /* Accumulate batch time */
- total_time += (end_batch - begin_batch);
-
- TEST_LPM_ASSERT((status < -ENOENT) ||
- (next_hop_return == next_hop_add));
- }
-
- avg_ticks = (uint32_t) div64(total_time, ITERATIONS);
- printf("Average LPM Lookup: %u cycles\n", avg_ticks);
-
- /* Delete */
- status = 0;
- begin = rte_rdtsc();
-
- for (i = 0; i < NUM_ROUTE_ENTRIES; i++) {
- /* rte_lpm_delete(lpm, ip, depth) */
- status += rte_lpm_delete(lpm, mae_west_tbl[i].ip,
- mae_west_tbl[i].depth);
- }
-
- end = rte_rdtsc();
-
- TEST_LPM_ASSERT(status == 0);
-
- avg_ticks = (uint32_t) div64((end - begin), NUM_ROUTE_ENTRIES);
-
- printf("Average LPM Delete: %u cycles\n", avg_ticks);
-
- rte_lpm_delete_all(lpm);
- rte_lpm_free(lpm);
-
- return PASS;
-}
-
-
-