1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015 Intel Corporation
7 #include <rte_cycles.h>
9 #include <rte_hash_crc.h>
10 #include <rte_spinlock.h>
11 #include <rte_launch.h>
16 * Check condition and return an error if true. Assumes that "handle" is the
17 * name of the hash structure pointer to be freed.
19 #define RETURN_IF_ERROR(cond, str, ...) do { \
21 printf("ERROR line %d: " str "\n", __LINE__, \
24 rte_hash_free(handle); \
36 uint32_t num_iterations
;
40 } tbl_scaling_test_params
;
42 static rte_atomic64_t gcycles
;
44 static int test_hash_scaling_worker(__attribute__((unused
)) void *arg
)
47 uint32_t thr_id
= rte_sys_gettid();
48 uint64_t begin
, cycles
= 0;
50 switch (tbl_scaling_test_params
.locking_mode
) {
54 for (i
= 0; i
< tbl_scaling_test_params
.num_iterations
; i
++) {
55 /* different threads get different keys because
56 we use the thread-id in the key computation
58 key
= rte_hash_crc(&i
, sizeof(i
), thr_id
);
59 begin
= rte_rdtsc_precise();
60 rte_spinlock_lock(tbl_scaling_test_params
.lock
);
61 rte_hash_add_key(tbl_scaling_test_params
.h
, &key
);
62 rte_spinlock_unlock(tbl_scaling_test_params
.lock
);
63 cycles
+= rte_rdtsc_precise() - begin
;
69 for (i
= 0; i
< tbl_scaling_test_params
.num_iterations
; i
++) {
70 key
= rte_hash_crc(&i
, sizeof(i
), thr_id
);
71 begin
= rte_rdtsc_precise();
72 rte_spinlock_lock_tm(tbl_scaling_test_params
.lock
);
73 rte_hash_add_key(tbl_scaling_test_params
.h
, &key
);
74 rte_spinlock_unlock_tm(tbl_scaling_test_params
.lock
);
75 cycles
+= rte_rdtsc_precise() - begin
;
81 for (i
= 0; i
< tbl_scaling_test_params
.num_iterations
; i
++) {
82 key
= rte_hash_crc(&i
, sizeof(i
), thr_id
);
83 begin
= rte_rdtsc_precise();
84 rte_hash_add_key(tbl_scaling_test_params
.h
, &key
);
85 cycles
+= rte_rdtsc_precise() - begin
;
89 rte_atomic64_add(&gcycles
, cycles
);
95 * Do scalability perf tests.
98 test_hash_scaling(int locking_mode
)
100 static unsigned calledCount
= 1;
101 uint32_t num_iterations
= 1024*1024;
103 struct rte_hash_parameters hash_params
= {
104 .entries
= num_iterations
*2,
105 .key_len
= sizeof(key
),
106 .hash_func
= rte_hash_crc
,
107 .hash_func_init_val
= 0,
108 .socket_id
= rte_socket_id(),
109 .extra_flag
= RTE_HASH_EXTRA_FLAGS_TRANS_MEM_SUPPORT
111 struct rte_hash
*handle
;
112 char name
[RTE_HASH_NAMESIZE
];
115 rte_spinlock_init(&lock
);
117 snprintf(name
, 32, "test%u", calledCount
++);
118 hash_params
.name
= name
;
120 handle
= rte_hash_create(&hash_params
);
121 RETURN_IF_ERROR(handle
== NULL
, "hash creation failed");
123 tbl_scaling_test_params
.num_iterations
=
124 num_iterations
/rte_lcore_count();
125 tbl_scaling_test_params
.h
= handle
;
126 tbl_scaling_test_params
.lock
= &lock
;
127 tbl_scaling_test_params
.locking_mode
= locking_mode
;
129 rte_atomic64_init(&gcycles
);
130 rte_atomic64_clear(&gcycles
);
132 /* fill up to initial size */
133 for (i
= 0; i
< num_iterations
; i
++) {
134 key
= rte_hash_crc(&i
, sizeof(i
), 0xabcdabcd);
135 rte_hash_add_key(tbl_scaling_test_params
.h
, &key
);
138 rte_eal_mp_remote_launch(test_hash_scaling_worker
, NULL
, CALL_MASTER
);
139 rte_eal_mp_wait_lcore();
141 unsigned long long int cycles_per_operation
=
142 rte_atomic64_read(&gcycles
)/
143 (tbl_scaling_test_params
.num_iterations
*rte_lcore_count());
144 const char *lock_name
;
146 switch (locking_mode
) {
148 lock_name
= "normal spinlock";
151 lock_name
= "lock elision";
154 lock_name
= "null lock";
156 printf("--------------------------------------------------------\n");
157 printf("Cores: %d; %s mode -> cycles per operation: %llu\n",
158 rte_lcore_count(), lock_name
, cycles_per_operation
);
159 printf("--------------------------------------------------------\n");
161 printf(">>>%d,%s,%llu\n", rte_lcore_count(), lock_name
,
162 cycles_per_operation
);
164 rte_hash_free(handle
);
169 test_hash_scaling_main(void)
173 if (rte_lcore_count() == 1)
174 r
= test_hash_scaling(NULL_LOCK
);
177 r
= test_hash_scaling(NORMAL_LOCK
);
179 if (!rte_tm_supported()) {
180 printf("Hardware transactional memory (lock elision) is NOT supported\n");
183 printf("Hardware transactional memory (lock elision) is supported\n");
186 r
= test_hash_scaling(LOCK_ELISION
);
191 REGISTER_TEST_COMMAND(hash_scaling_autotest
, test_hash_scaling_main
);