X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest%2Ftest_hash_perf.c;h=a438eae6c87e2522fdd0592c3349b009e529b980;hb=ba77f3e171733b49d7c991f03b97f0df6c85c4d1;hp=e9a522b5ac6ca8db2569ac7701f1fff59c9e2a42;hpb=473d1bebce43d9c08b8195c45ff022fb26bca594;p=dpdk.git diff --git a/app/test/test_hash_perf.c b/app/test/test_hash_perf.c index e9a522b5ac..a438eae6c8 100644 --- a/app/test/test_hash_perf.c +++ b/app/test/test_hash_perf.c @@ -1,34 +1,5 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2015 Intel Corporation */ #include @@ -47,9 +18,11 @@ #include "test.h" #define MAX_ENTRIES (1 << 19) -#define KEYS_TO_ADD (MAX_ENTRIES * 3 / 4) /* 75% table utilization */ +#define KEYS_TO_ADD (MAX_ENTRIES) +#define ADD_PERCENT 0.75 /* 75% table utilization */ #define NUM_LOOKUPS (KEYS_TO_ADD * 5) /* Loop among keys added, several times */ -#define BUCKET_SIZE 4 +/* BUCKET_SIZE should be same as RTE_HASH_BUCKET_ENTRIES in rte_hash library */ +#define BUCKET_SIZE 8 #define NUM_BUCKETS (MAX_ENTRIES / BUCKET_SIZE) #define MAX_KEYSIZE 64 #define NUM_KEYSIZES 10 @@ -80,41 +53,54 @@ static uint32_t hashtest_key_lens[] = { struct rte_hash *h[NUM_KEYSIZES]; /* Array that stores if a slot is full */ -uint8_t slot_taken[MAX_ENTRIES]; +static uint8_t slot_taken[MAX_ENTRIES]; /* Array to store number of cycles per operation */ -uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS][2][2]; +static uint64_t cycles[NUM_KEYSIZES][NUM_OPERATIONS][2][2]; /* Array to store all input keys */ -uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; +static uint8_t keys[KEYS_TO_ADD][MAX_KEYSIZE]; /* Array to store the precomputed hash for 'keys' */ -hash_sig_t signatures[KEYS_TO_ADD]; +static hash_sig_t signatures[KEYS_TO_ADD]; /* Array to store how many busy entries have each bucket */ -uint8_t buckets[NUM_BUCKETS]; +static uint8_t buckets[NUM_BUCKETS]; /* Array to store the positions where keys are added */ -int32_t positions[KEYS_TO_ADD]; +static int32_t positions[KEYS_TO_ADD]; /* Parameters used for hash table in unit test functions. */ static struct rte_hash_parameters ut_params = { .entries = MAX_ENTRIES, - .bucket_entries = BUCKET_SIZE, .hash_func = rte_jhash, .hash_func_init_val = 0, }; static int -create_table(unsigned with_data, unsigned table_index) +create_table(unsigned int with_data, unsigned int table_index, + unsigned int with_locks, unsigned int ext) { char name[RTE_HASH_NAMESIZE]; if (with_data) /* Table will store 8-byte data */ - sprintf(name, "test_hash%d_data", hashtest_key_lens[table_index]); + snprintf(name, sizeof(name), "test_hash%u_data", + hashtest_key_lens[table_index]); else - sprintf(name, "test_hash%d", hashtest_key_lens[table_index]); + snprintf(name, sizeof(name), "test_hash%u", + hashtest_key_lens[table_index]); + + + if (with_locks) + ut_params.extra_flag = + RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT + | RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY; + else + ut_params.extra_flag = 0; + + if (ext) + ut_params.extra_flag |= RTE_HASH_EXTRA_FLAGS_EXT_TABLE; ut_params.name = name; ut_params.key_len = hashtest_key_lens[table_index]; @@ -137,15 +123,21 @@ create_table(unsigned with_data, unsigned table_index) /* Shuffle the keys that have been added, so lookups will be totally random */ static void -shuffle_input_keys(unsigned table_index) +shuffle_input_keys(unsigned int table_index, unsigned int ext) { unsigned i; uint32_t swap_idx; - uint8_t temp_key[RTE_HASH_KEY_LENGTH_MAX]; + uint8_t temp_key[MAX_KEYSIZE]; hash_sig_t temp_signature; int32_t temp_position; + unsigned int keys_to_add; + + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; - for (i = KEYS_TO_ADD - 1; i > 0; i--) { + for (i = keys_to_add - 1; i > 0; i--) { swap_idx = rte_rand() % i; memcpy(temp_key, keys[i], hashtest_key_lens[table_index]); @@ -167,14 +159,20 @@ shuffle_input_keys(unsigned table_index) * ALL can fit in hash table (no errors) */ static int -get_input_keys(unsigned with_pushes, unsigned table_index) +get_input_keys(unsigned int with_pushes, unsigned int table_index, + unsigned int ext) { unsigned i, j; unsigned bucket_idx, incr, success = 1; uint8_t k = 0; int32_t ret; const uint32_t bucket_bitmask = NUM_BUCKETS - 1; + unsigned int keys_to_add; + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; /* Reset all arrays */ for (i = 0; i < MAX_ENTRIES; i++) slot_taken[i] = 0; @@ -191,7 +189,7 @@ get_input_keys(unsigned with_pushes, unsigned table_index) * Regardless a key has been added correctly or not (success), * the next one to try will be increased by 1. */ - for (i = 0; i < KEYS_TO_ADD;) { + for (i = 0; i < keys_to_add;) { incr = 0; if (i != 0) { keys[i][0] = ++k; @@ -255,21 +253,27 @@ get_input_keys(unsigned with_pushes, unsigned table_index) } static int -timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) +timed_adds(unsigned int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) { unsigned i; const uint64_t start_tsc = rte_rdtsc(); void *data; int32_t ret; + unsigned int keys_to_add; + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; - for (i = 0; i < KEYS_TO_ADD; i++) { + for (i = 0; i < keys_to_add; i++) { data = (void *) ((uintptr_t) signatures[i]); if (with_hash && with_data) { ret = rte_hash_add_key_with_hash_data(h[table_index], (const void *) keys[i], signatures[i], data); if (ret < 0) { - printf("Failed to add key number %u\n", ret); + printf("H+D: Failed to add key number %u\n", i); return -1; } } else if (with_hash && !with_data) { @@ -279,7 +283,7 @@ timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) if (ret >= 0) positions[i] = ret; else { - printf("Failed to add key number %u\n", ret); + printf("H: Failed to add key number %u\n", i); return -1; } } else if (!with_hash && with_data) { @@ -287,7 +291,7 @@ timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) (const void *) keys[i], data); if (ret < 0) { - printf("Failed to add key number %u\n", ret); + printf("D: Failed to add key number %u\n", i); return -1; } } else { @@ -295,7 +299,7 @@ timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) if (ret >= 0) positions[i] = ret; else { - printf("Failed to add key number %u\n", ret); + printf("Failed to add key number %u\n", i); return -1; } } @@ -304,22 +308,31 @@ timed_adds(unsigned with_hash, unsigned with_data, unsigned table_index) const uint64_t end_tsc = rte_rdtsc(); const uint64_t time_taken = end_tsc - start_tsc; - cycles[table_index][ADD][with_hash][with_data] = time_taken/KEYS_TO_ADD; + cycles[table_index][ADD][with_hash][with_data] = time_taken/keys_to_add; return 0; } static int -timed_lookups(unsigned with_hash, unsigned with_data, unsigned table_index) +timed_lookups(unsigned int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) { unsigned i, j; const uint64_t start_tsc = rte_rdtsc(); void *ret_data; void *expected_data; int32_t ret; - - for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD; j++) { + unsigned int keys_to_add, num_lookups; + + if (!ext) { + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + num_lookups = NUM_LOOKUPS * ADD_PERCENT; + } else { + keys_to_add = KEYS_TO_ADD; + num_lookups = NUM_LOOKUPS; + } + for (i = 0; i < num_lookups / keys_to_add; i++) { + for (j = 0; j < keys_to_add; j++) { if (with_hash && with_data) { ret = rte_hash_lookup_with_hash_data(h[table_index], (const void *) keys[j], @@ -372,13 +385,14 @@ timed_lookups(unsigned with_hash, unsigned with_data, unsigned table_index) const uint64_t end_tsc = rte_rdtsc(); const uint64_t time_taken = end_tsc - start_tsc; - cycles[table_index][LOOKUP][with_hash][with_data] = time_taken/NUM_LOOKUPS; + cycles[table_index][LOOKUP][with_hash][with_data] = time_taken/num_lookups; return 0; } static int -timed_lookups_multi(unsigned with_data, unsigned table_index) +timed_lookups_multi(unsigned int with_data, unsigned int table_index, + unsigned int ext) { unsigned i, j, k; int32_t positions_burst[BURST_SIZE]; @@ -387,11 +401,20 @@ timed_lookups_multi(unsigned with_data, unsigned table_index) void *ret_data[BURST_SIZE]; uint64_t hit_mask; int ret; + unsigned int keys_to_add, num_lookups; + + if (!ext) { + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + num_lookups = NUM_LOOKUPS * ADD_PERCENT; + } else { + keys_to_add = KEYS_TO_ADD; + num_lookups = NUM_LOOKUPS; + } const uint64_t start_tsc = rte_rdtsc(); - for (i = 0; i < NUM_LOOKUPS/KEYS_TO_ADD; i++) { - for (j = 0; j < KEYS_TO_ADD/BURST_SIZE; j++) { + for (i = 0; i < num_lookups/keys_to_add; i++) { + for (j = 0; j < keys_to_add/BURST_SIZE; j++) { for (k = 0; k < BURST_SIZE; k++) keys_burst[k] = keys[j * BURST_SIZE + k]; if (with_data) { @@ -439,19 +462,25 @@ timed_lookups_multi(unsigned with_data, unsigned table_index) const uint64_t end_tsc = rte_rdtsc(); const uint64_t time_taken = end_tsc - start_tsc; - cycles[table_index][LOOKUP_MULTI][0][with_data] = time_taken/NUM_LOOKUPS; + cycles[table_index][LOOKUP_MULTI][0][with_data] = time_taken/num_lookups; return 0; } static int -timed_deletes(unsigned with_hash, unsigned with_data, unsigned table_index) +timed_deletes(unsigned int with_hash, unsigned int with_data, + unsigned int table_index, unsigned int ext) { unsigned i; const uint64_t start_tsc = rte_rdtsc(); int32_t ret; + unsigned int keys_to_add; + if (!ext) + keys_to_add = KEYS_TO_ADD * ADD_PERCENT; + else + keys_to_add = KEYS_TO_ADD; - for (i = 0; i < KEYS_TO_ADD; i++) { + for (i = 0; i < keys_to_add; i++) { /* There are no delete functions with data, so just call two functions */ if (with_hash) ret = rte_hash_del_key_with_hash(h[table_index], @@ -463,7 +492,7 @@ timed_deletes(unsigned with_hash, unsigned with_data, unsigned table_index) if (ret >= 0) positions[i] = ret; else { - printf("Failed to add key number %u\n", ret); + printf("Failed to delete key number %u\n", i); return -1; } } @@ -471,7 +500,7 @@ timed_deletes(unsigned with_hash, unsigned with_data, unsigned table_index) const uint64_t end_tsc = rte_rdtsc(); const uint64_t time_taken = end_tsc - start_tsc; - cycles[table_index][DELETE][with_hash][with_data] = time_taken/KEYS_TO_ADD; + cycles[table_index][DELETE][with_hash][with_data] = time_taken/keys_to_add; return 0; } @@ -489,7 +518,8 @@ reset_table(unsigned table_index) } static int -run_all_tbl_perf_tests(unsigned with_pushes) +run_all_tbl_perf_tests(unsigned int with_pushes, unsigned int with_locks, + unsigned int ext) { unsigned i, j, with_data, with_hash; @@ -498,25 +528,25 @@ run_all_tbl_perf_tests(unsigned with_pushes) for (with_data = 0; with_data <= 1; with_data++) { for (i = 0; i < NUM_KEYSIZES; i++) { - if (create_table(with_data, i) < 0) + if (create_table(with_data, i, with_locks, ext) < 0) return -1; - if (get_input_keys(with_pushes, i) < 0) + if (get_input_keys(with_pushes, i, ext) < 0) return -1; for (with_hash = 0; with_hash <= 1; with_hash++) { - if (timed_adds(with_hash, with_data, i) < 0) + if (timed_adds(with_hash, with_data, i, ext) < 0) return -1; for (j = 0; j < NUM_SHUFFLES; j++) - shuffle_input_keys(i); + shuffle_input_keys(i, ext); - if (timed_lookups(with_hash, with_data, i) < 0) + if (timed_lookups(with_hash, with_data, i, ext) < 0) return -1; - if (timed_lookups_multi(with_data, i) < 0) + if (timed_lookups_multi(with_data, i, ext) < 0) return -1; - if (timed_deletes(with_hash, with_data, i) < 0) + if (timed_deletes(with_hash, with_data, i, ext) < 0) return -1; /* Print a dot to show progress on operations */ @@ -641,24 +671,31 @@ fbk_hash_perf_test(void) static int test_hash_perf(void) { - unsigned with_pushes; - - for (with_pushes = 0; with_pushes <= 1; with_pushes++) { - if (with_pushes == 0) - printf("\nALL ELEMENTS IN PRIMARY LOCATION\n"); + unsigned int with_pushes, with_locks; + for (with_locks = 0; with_locks <= 1; with_locks++) { + if (with_locks) + printf("\nWith locks in the code\n"); else - printf("\nELEMENTS IN PRIMARY OR SECONDARY LOCATION\n"); - if (run_all_tbl_perf_tests(with_pushes) < 0) - return -1; + printf("\nWithout locks in the code\n"); + for (with_pushes = 0; with_pushes <= 1; with_pushes++) { + if (with_pushes == 0) + printf("\nALL ELEMENTS IN PRIMARY LOCATION\n"); + else + printf("\nELEMENTS IN PRIMARY OR SECONDARY LOCATION\n"); + if (run_all_tbl_perf_tests(with_pushes, with_locks, 0) < 0) + return -1; + } } + + printf("\n EXTENDABLE BUCKETS PERFORMANCE\n"); + + if (run_all_tbl_perf_tests(1, 0, 1) < 0) + return -1; + if (fbk_hash_perf_test() < 0) return -1; return 0; } -static struct test_command hash_perf_cmd = { - .command = "hash_perf_autotest", - .callback = test_hash_perf, -}; -REGISTER_TEST_COMMAND(hash_perf_cmd); +REGISTER_TEST_COMMAND(hash_perf_autotest, test_hash_perf);