5156dfc0c32d776be906e2b16d037a3ab6fccfce
[dpdk.git] / app / test / test_hash_functions.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39 #include <errno.h>
40 #include <sys/queue.h>
41
42 #include <rte_cycles.h>
43 #include <rte_random.h>
44 #include <rte_hash.h>
45 #include <rte_jhash.h>
46 #include <rte_hash_crc.h>
47
48 #include "test.h"
49
50 /*******************************************************************************
51  * Hash function performance test configuration section. Each performance test
52  * will be performed HASHTEST_ITERATIONS times.
53  *
54  * The three arrays below control what tests are performed. Every combination
55  * from the array entries is tested.
56  */
57 #define HASHTEST_ITERATIONS 1000000
58
59 static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc};
60 static uint32_t hashtest_initvals[] = {0, 0xdeadbeef};
61 static uint32_t hashtest_key_lens[] = {
62         4, 8, 16, 32, 48, 64, /* standard key sizes */
63         9,                    /* IPv4 SRC + DST + protocol, unpadded */
64         13,                   /* IPv4 5-tuple, unpadded */
65         37,                   /* IPv6 5-tuple, unpadded */
66         40                    /* IPv6 5-tuple, padded to 8-byte boundary */
67 };
68 /******************************************************************************/
69
70 /*
71  * To help print out name of hash functions.
72  */
73 static const char *
74 get_hash_name(rte_hash_function f)
75 {
76         if (f == rte_jhash)
77                 return "jhash";
78
79         if (f == rte_hash_crc)
80                 return "rte_hash_crc";
81
82         return "UnknownHash";
83 }
84
85 /*
86  * Test a hash function.
87  */
88 static void
89 run_hash_func_perf_test(uint32_t key_len, uint32_t init_val,
90                 rte_hash_function f)
91 {
92         static uint8_t key[HASHTEST_ITERATIONS][RTE_HASH_KEY_LENGTH_MAX];
93         uint64_t ticks, start, end;
94         unsigned i, j;
95
96         for (i = 0; i < HASHTEST_ITERATIONS; i++) {
97                 for (j = 0; j < key_len; j++)
98                         key[i][j] = (uint8_t) rte_rand();
99         }
100
101         start = rte_rdtsc();
102         for (i = 0; i < HASHTEST_ITERATIONS; i++)
103                 f(key[i], key_len, init_val);
104         end = rte_rdtsc();
105         ticks = end - start;
106
107         printf("%-12s, %-18u, %-13u, %.02f\n", get_hash_name(f), (unsigned) key_len,
108                         (unsigned) init_val, (double)ticks / HASHTEST_ITERATIONS);
109 }
110
111 /*
112  * Test all hash functions.
113  */
114 static void
115 run_hash_func_perf_tests(void)
116 {
117         unsigned i, j, k;
118
119         printf(" *** Hash function performance test results ***\n");
120         printf(" Number of iterations for each test = %d\n",
121                         HASHTEST_ITERATIONS);
122         printf("Hash Func.  , Key Length (bytes), Initial value, Ticks/Op.\n");
123
124         for (i = 0; i < RTE_DIM(hashtest_initvals); i++) {
125                 for (j = 0; j < RTE_DIM(hashtest_key_lens); j++) {
126                         for (k = 0; k < RTE_DIM(hashtest_funcs); k++) {
127                                 run_hash_func_perf_test(hashtest_key_lens[j],
128                                                 hashtest_initvals[i],
129                                                 hashtest_funcs[k]);
130                         }
131                 }
132         }
133 }
134
135 static int
136 test_hash_functions(void)
137 {
138         run_hash_func_perf_tests();
139
140         return 0;
141 }
142
143 static struct test_command hash_functions_cmd = {
144         .command = "hash_functions_autotest",
145         .callback = test_hash_functions,
146 };
147 REGISTER_TEST_COMMAND(hash_functions_cmd);