1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
3759cf9b5SJoyce Kong * Copyright(c) 2019 Arm Limited
4a9de470cSBruce Richardson */
5a9de470cSBruce Richardson
6a9de470cSBruce Richardson
7a9de470cSBruce Richardson #include <stdio.h>
8a9de470cSBruce Richardson #include <inttypes.h>
9a9de470cSBruce Richardson #include <rte_ring.h>
10a9de470cSBruce Richardson #include <rte_cycles.h>
11a9de470cSBruce Richardson #include <rte_launch.h>
12a9de470cSBruce Richardson #include <rte_pause.h>
13759cf9b5SJoyce Kong #include <string.h>
14a9de470cSBruce Richardson
15a9de470cSBruce Richardson #include "test.h"
161fa5d009SHonnappa Nagarahalli #include "test_ring.h"
17a9de470cSBruce Richardson
18a9de470cSBruce Richardson /*
191fa5d009SHonnappa Nagarahalli * Ring performance test cases, measures performance of various operations
201fa5d009SHonnappa Nagarahalli * using rdtsc for legacy and 16B size ring elements.
21a9de470cSBruce Richardson */
22a9de470cSBruce Richardson
23a9de470cSBruce Richardson #define RING_NAME "RING_PERF"
24a9de470cSBruce Richardson #define RING_SIZE 4096
25*a4cb5461SPaul Szczepanek #define MAX_BURST 256
26a9de470cSBruce Richardson
27a9de470cSBruce Richardson /*
28a9de470cSBruce Richardson * the sizes to enqueue and dequeue in testing
29a9de470cSBruce Richardson * (marked volatile so they won't be seen as compile-time constants)
30a9de470cSBruce Richardson */
31*a4cb5461SPaul Szczepanek static const volatile unsigned int bulk_sizes[] = { 8, 32, 64, 128, 256 };
32a9de470cSBruce Richardson
33a9de470cSBruce Richardson struct lcore_pair {
34a9de470cSBruce Richardson unsigned c1, c2;
35a9de470cSBruce Richardson };
36a9de470cSBruce Richardson
37a9de470cSBruce Richardson static volatile unsigned lcore_count = 0;
38a9de470cSBruce Richardson
391fa5d009SHonnappa Nagarahalli static void
test_ring_print_test_string(unsigned int api_type,int esize,unsigned int bsz,double value)401fa5d009SHonnappa Nagarahalli test_ring_print_test_string(unsigned int api_type, int esize,
411fa5d009SHonnappa Nagarahalli unsigned int bsz, double value)
421fa5d009SHonnappa Nagarahalli {
431fa5d009SHonnappa Nagarahalli if (esize == -1)
441fa5d009SHonnappa Nagarahalli printf("legacy APIs");
451fa5d009SHonnappa Nagarahalli else
46*a4cb5461SPaul Szczepanek printf("elem APIs (size:%2dB)", esize);
471fa5d009SHonnappa Nagarahalli
481fa5d009SHonnappa Nagarahalli if (api_type == TEST_RING_IGNORE_API_TYPE)
491fa5d009SHonnappa Nagarahalli return;
501fa5d009SHonnappa Nagarahalli
511fa5d009SHonnappa Nagarahalli if ((api_type & TEST_RING_THREAD_DEF) == TEST_RING_THREAD_DEF)
52*a4cb5461SPaul Szczepanek printf(" - default enqueue/dequeue");
531fa5d009SHonnappa Nagarahalli else if ((api_type & TEST_RING_THREAD_SPSC) == TEST_RING_THREAD_SPSC)
54*a4cb5461SPaul Szczepanek printf(" - SP/SC");
551fa5d009SHonnappa Nagarahalli else if ((api_type & TEST_RING_THREAD_MPMC) == TEST_RING_THREAD_MPMC)
56*a4cb5461SPaul Szczepanek printf(" - MP/MC");
571fa5d009SHonnappa Nagarahalli
581fa5d009SHonnappa Nagarahalli if ((api_type & TEST_RING_ELEM_SINGLE) == TEST_RING_ELEM_SINGLE)
59*a4cb5461SPaul Szczepanek printf(" - single - ");
601fa5d009SHonnappa Nagarahalli else if ((api_type & TEST_RING_ELEM_BULK) == TEST_RING_ELEM_BULK)
61*a4cb5461SPaul Szczepanek printf(" - bulk (n:%-3u) - ", bsz);
621fa5d009SHonnappa Nagarahalli else if ((api_type & TEST_RING_ELEM_BURST) == TEST_RING_ELEM_BURST)
63*a4cb5461SPaul Szczepanek printf(" - burst (n:%-3u) - ", bsz);
64*a4cb5461SPaul Szczepanek else if ((api_type & (TEST_RING_ELEM_BURST_ZC |
65*a4cb5461SPaul Szczepanek TEST_RING_ELEM_BURST_ZC_COMPRESS_PTR_16 |
66*a4cb5461SPaul Szczepanek TEST_RING_ELEM_BURST_ZC_COMPRESS_PTR_32)) != 0)
67*a4cb5461SPaul Szczepanek printf(" - burst zero copy (n:%-3u) - ", bsz);
681fa5d009SHonnappa Nagarahalli
69*a4cb5461SPaul Szczepanek printf("cycles per elem: %.3F\n", value);
701fa5d009SHonnappa Nagarahalli }
711fa5d009SHonnappa Nagarahalli
72a9de470cSBruce Richardson /**** Functions to analyse our core mask to get cores for different tests ***/
73a9de470cSBruce Richardson
74a9de470cSBruce Richardson static int
get_two_hyperthreads(struct lcore_pair * lcp)75a9de470cSBruce Richardson get_two_hyperthreads(struct lcore_pair *lcp)
76a9de470cSBruce Richardson {
77a9de470cSBruce Richardson unsigned id1, id2;
78a9de470cSBruce Richardson unsigned c1, c2, s1, s2;
79a9de470cSBruce Richardson RTE_LCORE_FOREACH(id1) {
80a9de470cSBruce Richardson /* inner loop just re-reads all id's. We could skip the first few
81a9de470cSBruce Richardson * elements, but since number of cores is small there is little point
82a9de470cSBruce Richardson */
83a9de470cSBruce Richardson RTE_LCORE_FOREACH(id2) {
84a9de470cSBruce Richardson if (id1 == id2)
85a9de470cSBruce Richardson continue;
86de307f7aSStephen Hemminger
87de307f7aSStephen Hemminger c1 = rte_lcore_to_cpu_id(id1);
88de307f7aSStephen Hemminger c2 = rte_lcore_to_cpu_id(id2);
89de307f7aSStephen Hemminger s1 = rte_lcore_to_socket_id(id1);
90de307f7aSStephen Hemminger s2 = rte_lcore_to_socket_id(id2);
91a9de470cSBruce Richardson if ((c1 == c2) && (s1 == s2)){
92a9de470cSBruce Richardson lcp->c1 = id1;
93a9de470cSBruce Richardson lcp->c2 = id2;
94a9de470cSBruce Richardson return 0;
95a9de470cSBruce Richardson }
96a9de470cSBruce Richardson }
97a9de470cSBruce Richardson }
98a9de470cSBruce Richardson return 1;
99a9de470cSBruce Richardson }
100a9de470cSBruce Richardson
101a9de470cSBruce Richardson static int
get_two_cores(struct lcore_pair * lcp)102a9de470cSBruce Richardson get_two_cores(struct lcore_pair *lcp)
103a9de470cSBruce Richardson {
104a9de470cSBruce Richardson unsigned id1, id2;
105a9de470cSBruce Richardson unsigned c1, c2, s1, s2;
106a9de470cSBruce Richardson RTE_LCORE_FOREACH(id1) {
107a9de470cSBruce Richardson RTE_LCORE_FOREACH(id2) {
108a9de470cSBruce Richardson if (id1 == id2)
109a9de470cSBruce Richardson continue;
110de307f7aSStephen Hemminger
111de307f7aSStephen Hemminger c1 = rte_lcore_to_cpu_id(id1);
112de307f7aSStephen Hemminger c2 = rte_lcore_to_cpu_id(id2);
113de307f7aSStephen Hemminger s1 = rte_lcore_to_socket_id(id1);
114de307f7aSStephen Hemminger s2 = rte_lcore_to_socket_id(id2);
115a9de470cSBruce Richardson if ((c1 != c2) && (s1 == s2)){
116a9de470cSBruce Richardson lcp->c1 = id1;
117a9de470cSBruce Richardson lcp->c2 = id2;
118a9de470cSBruce Richardson return 0;
119a9de470cSBruce Richardson }
120a9de470cSBruce Richardson }
121a9de470cSBruce Richardson }
122a9de470cSBruce Richardson return 1;
123a9de470cSBruce Richardson }
124a9de470cSBruce Richardson
125a9de470cSBruce Richardson static int
get_two_sockets(struct lcore_pair * lcp)126a9de470cSBruce Richardson get_two_sockets(struct lcore_pair *lcp)
127a9de470cSBruce Richardson {
128a9de470cSBruce Richardson unsigned id1, id2;
129a9de470cSBruce Richardson unsigned s1, s2;
130a9de470cSBruce Richardson RTE_LCORE_FOREACH(id1) {
131a9de470cSBruce Richardson RTE_LCORE_FOREACH(id2) {
132a9de470cSBruce Richardson if (id1 == id2)
133a9de470cSBruce Richardson continue;
134de307f7aSStephen Hemminger s1 = rte_lcore_to_socket_id(id1);
135de307f7aSStephen Hemminger s2 = rte_lcore_to_socket_id(id2);
136a9de470cSBruce Richardson if (s1 != s2){
137a9de470cSBruce Richardson lcp->c1 = id1;
138a9de470cSBruce Richardson lcp->c2 = id2;
139a9de470cSBruce Richardson return 0;
140a9de470cSBruce Richardson }
141a9de470cSBruce Richardson }
142a9de470cSBruce Richardson }
143a9de470cSBruce Richardson return 1;
144a9de470cSBruce Richardson }
145a9de470cSBruce Richardson
146a9de470cSBruce Richardson /* Get cycle counts for dequeuing from an empty ring. Should be 2 or 3 cycles */
147a9de470cSBruce Richardson static void
test_empty_dequeue(struct rte_ring * r,const int esize,const unsigned int api_type)1481fa5d009SHonnappa Nagarahalli test_empty_dequeue(struct rte_ring *r, const int esize,
1491fa5d009SHonnappa Nagarahalli const unsigned int api_type)
150a9de470cSBruce Richardson {
151*a4cb5461SPaul Szczepanek const unsigned int iter_shift = 29;
1521fa5d009SHonnappa Nagarahalli const unsigned int iterations = 1 << iter_shift;
1531fa5d009SHonnappa Nagarahalli unsigned int i = 0;
154a9de470cSBruce Richardson void *burst[MAX_BURST];
155a9de470cSBruce Richardson
156*a4cb5461SPaul Szczepanek const unsigned int bulk_iterations = iterations / bulk_sizes[0];
1571fa5d009SHonnappa Nagarahalli const uint64_t start = rte_rdtsc();
158*a4cb5461SPaul Szczepanek for (i = 0; i < bulk_iterations; i++)
1591fa5d009SHonnappa Nagarahalli test_ring_dequeue(r, burst, esize, bulk_sizes[0], api_type);
1601fa5d009SHonnappa Nagarahalli const uint64_t end = rte_rdtsc();
161a9de470cSBruce Richardson
1621fa5d009SHonnappa Nagarahalli test_ring_print_test_string(api_type, esize, bulk_sizes[0],
163*a4cb5461SPaul Szczepanek ((double)end - start) / iterations);
164a9de470cSBruce Richardson }
165a9de470cSBruce Richardson
166*a4cb5461SPaul Szczepanek /* describes the ring used by the enqueue and dequeue thread */
167*a4cb5461SPaul Szczepanek struct ring_params {
168a9de470cSBruce Richardson struct rte_ring *r;
169*a4cb5461SPaul Szczepanek unsigned int elem_size;
170*a4cb5461SPaul Szczepanek unsigned int bulk_sizes_i; /* index into bulk_size array */
171*a4cb5461SPaul Szczepanek unsigned int ring_flags; /* flags for test_ring_enqueue/dequeue */
172*a4cb5461SPaul Szczepanek };
173*a4cb5461SPaul Szczepanek
174*a4cb5461SPaul Szczepanek /* Used to specify enqueue and dequeue ring operations and their results */
175*a4cb5461SPaul Szczepanek struct thread_params {
176*a4cb5461SPaul Szczepanek struct ring_params *ring_params;
177*a4cb5461SPaul Szczepanek double *results; /* result array size must be equal to bulk_sizes */
178a9de470cSBruce Richardson };
179a9de470cSBruce Richardson
180a9de470cSBruce Richardson /*
1811fa5d009SHonnappa Nagarahalli * Helper function to call bulk SP/MP enqueue functions.
1821fa5d009SHonnappa Nagarahalli * flag == 0 -> enqueue
1831fa5d009SHonnappa Nagarahalli * flag == 1 -> dequeue
184a9de470cSBruce Richardson */
1851fa5d009SHonnappa Nagarahalli static __rte_always_inline int
enqueue_dequeue_bulk_helper(const unsigned int flag,struct thread_params * p)186*a4cb5461SPaul Szczepanek enqueue_dequeue_bulk_helper(const unsigned int flag, struct thread_params *p)
187a9de470cSBruce Richardson {
1881fa5d009SHonnappa Nagarahalli int ret;
189*a4cb5461SPaul Szczepanek const unsigned int iter_shift = 22;
1901fa5d009SHonnappa Nagarahalli const unsigned int iterations = 1 << iter_shift;
1911fa5d009SHonnappa Nagarahalli unsigned int i;
1921fa5d009SHonnappa Nagarahalli void *burst = NULL;
193*a4cb5461SPaul Szczepanek unsigned int n_remaining;
194*a4cb5461SPaul Szczepanek const unsigned int bulk_n = bulk_sizes[p->ring_params->bulk_sizes_i];
195a9de470cSBruce Richardson
196e4eb7b06SPhil Yang #ifdef RTE_USE_C11_MEM_MODEL
197b6a7e685STyler Retzlaff if (rte_atomic_fetch_add_explicit(&lcore_count, 1, rte_memory_order_relaxed) + 1 != 2)
198e4eb7b06SPhil Yang #else
199a9de470cSBruce Richardson if (__sync_add_and_fetch(&lcore_count, 1) != 2)
200e4eb7b06SPhil Yang #endif
201a9de470cSBruce Richardson while(lcore_count != 2)
202a9de470cSBruce Richardson rte_pause();
203a9de470cSBruce Richardson
204*a4cb5461SPaul Szczepanek burst = test_ring_calloc(MAX_BURST, p->ring_params->elem_size);
2051fa5d009SHonnappa Nagarahalli if (burst == NULL)
2061fa5d009SHonnappa Nagarahalli return -1;
2071fa5d009SHonnappa Nagarahalli
208a9de470cSBruce Richardson const uint64_t sp_start = rte_rdtsc();
209*a4cb5461SPaul Szczepanek const unsigned int bulk_iterations = iterations / bulk_n;
210*a4cb5461SPaul Szczepanek for (i = 0; i < bulk_iterations; i++) {
211*a4cb5461SPaul Szczepanek n_remaining = bulk_n;
2121fa5d009SHonnappa Nagarahalli do {
2131fa5d009SHonnappa Nagarahalli if (flag == 0)
214*a4cb5461SPaul Szczepanek ret = test_ring_enqueue(p->ring_params->r,
215*a4cb5461SPaul Szczepanek burst,
216*a4cb5461SPaul Szczepanek p->ring_params->elem_size,
217*a4cb5461SPaul Szczepanek n_remaining,
218*a4cb5461SPaul Szczepanek p->ring_params->ring_flags);
2191fa5d009SHonnappa Nagarahalli else if (flag == 1)
220*a4cb5461SPaul Szczepanek ret = test_ring_dequeue(p->ring_params->r,
221*a4cb5461SPaul Szczepanek burst,
222*a4cb5461SPaul Szczepanek p->ring_params->elem_size,
223*a4cb5461SPaul Szczepanek n_remaining,
224*a4cb5461SPaul Szczepanek p->ring_params->ring_flags);
2251fa5d009SHonnappa Nagarahalli if (ret == 0)
226a9de470cSBruce Richardson rte_pause();
227*a4cb5461SPaul Szczepanek else
228*a4cb5461SPaul Szczepanek n_remaining -= ret;
229*a4cb5461SPaul Szczepanek } while (n_remaining > 0);
230*a4cb5461SPaul Szczepanek }
231a9de470cSBruce Richardson const uint64_t sp_end = rte_rdtsc();
232a9de470cSBruce Richardson
233*a4cb5461SPaul Szczepanek p->results[p->ring_params->bulk_sizes_i] =
234*a4cb5461SPaul Szczepanek ((double)sp_end - sp_start) / iterations;
235a9de470cSBruce Richardson
236a9de470cSBruce Richardson return 0;
237a9de470cSBruce Richardson }
238a9de470cSBruce Richardson
239a9de470cSBruce Richardson /*
2401fa5d009SHonnappa Nagarahalli * Function that uses rdtsc to measure timing for ring enqueue. Needs pair
2411fa5d009SHonnappa Nagarahalli * thread running dequeue_bulk function
2421fa5d009SHonnappa Nagarahalli */
2431fa5d009SHonnappa Nagarahalli static int
enqueue_bulk(void * p)2441fa5d009SHonnappa Nagarahalli enqueue_bulk(void *p)
2451fa5d009SHonnappa Nagarahalli {
2461fa5d009SHonnappa Nagarahalli struct thread_params *params = p;
2471fa5d009SHonnappa Nagarahalli
248*a4cb5461SPaul Szczepanek return enqueue_dequeue_bulk_helper(0, params);
2491fa5d009SHonnappa Nagarahalli }
2501fa5d009SHonnappa Nagarahalli
2511fa5d009SHonnappa Nagarahalli /*
252a9de470cSBruce Richardson * Function that uses rdtsc to measure timing for ring dequeue. Needs pair
253a9de470cSBruce Richardson * thread running enqueue_bulk function
254a9de470cSBruce Richardson */
255a9de470cSBruce Richardson static int
dequeue_bulk(void * p)256a9de470cSBruce Richardson dequeue_bulk(void *p)
257a9de470cSBruce Richardson {
258a9de470cSBruce Richardson struct thread_params *params = p;
259a9de470cSBruce Richardson
260*a4cb5461SPaul Szczepanek return enqueue_dequeue_bulk_helper(1, params);
261a9de470cSBruce Richardson }
262a9de470cSBruce Richardson
263a9de470cSBruce Richardson /*
264a9de470cSBruce Richardson * Function that calls the enqueue and dequeue bulk functions on pairs of cores.
265a9de470cSBruce Richardson * used to measure ring perf between hyperthreads, cores and sockets.
266a9de470cSBruce Richardson */
2671fa5d009SHonnappa Nagarahalli static int
run_on_core_pair(struct lcore_pair * cores,struct thread_params * param1,struct thread_params * param2)268*a4cb5461SPaul Szczepanek run_on_core_pair(struct lcore_pair *cores,
269*a4cb5461SPaul Szczepanek struct thread_params *param1, struct thread_params *param2)
270a9de470cSBruce Richardson {
271a9de470cSBruce Richardson unsigned i;
272*a4cb5461SPaul Szczepanek struct ring_params *ring_params = param1->ring_params;
2731fa5d009SHonnappa Nagarahalli
27471bdd8a1SPavan Nikhilesh for (i = 0; i < RTE_DIM(bulk_sizes); i++) {
275a9de470cSBruce Richardson lcore_count = 0;
276*a4cb5461SPaul Szczepanek ring_params->bulk_sizes_i = i;
277cb056611SStephen Hemminger if (cores->c1 == rte_get_main_lcore()) {
278*a4cb5461SPaul Szczepanek rte_eal_remote_launch(dequeue_bulk, param2, cores->c2);
279*a4cb5461SPaul Szczepanek enqueue_bulk(param1);
280a9de470cSBruce Richardson rte_eal_wait_lcore(cores->c2);
281a9de470cSBruce Richardson } else {
282*a4cb5461SPaul Szczepanek rte_eal_remote_launch(enqueue_bulk, param1, cores->c1);
283*a4cb5461SPaul Szczepanek rte_eal_remote_launch(dequeue_bulk, param2, cores->c2);
2841fa5d009SHonnappa Nagarahalli if (rte_eal_wait_lcore(cores->c1) < 0)
2851fa5d009SHonnappa Nagarahalli return -1;
2861fa5d009SHonnappa Nagarahalli if (rte_eal_wait_lcore(cores->c2) < 0)
2871fa5d009SHonnappa Nagarahalli return -1;
288a9de470cSBruce Richardson }
2891fa5d009SHonnappa Nagarahalli test_ring_print_test_string(
290*a4cb5461SPaul Szczepanek ring_params->ring_flags,
291*a4cb5461SPaul Szczepanek ring_params->elem_size,
292*a4cb5461SPaul Szczepanek bulk_sizes[i],
293*a4cb5461SPaul Szczepanek param1->results[i] + param2->results[i]);
294a9de470cSBruce Richardson }
2951fa5d009SHonnappa Nagarahalli
2961fa5d009SHonnappa Nagarahalli return 0;
297a9de470cSBruce Richardson }
298a9de470cSBruce Richardson
299b6a7e685STyler Retzlaff static RTE_ATOMIC(uint32_t) synchro;
300759cf9b5SJoyce Kong static uint64_t queue_count[RTE_MAX_LCORE];
301759cf9b5SJoyce Kong
302759cf9b5SJoyce Kong #define TIME_MS 100
303759cf9b5SJoyce Kong
304759cf9b5SJoyce Kong static int
load_loop_fn_helper(struct thread_params * p,const int esize)3051fa5d009SHonnappa Nagarahalli load_loop_fn_helper(struct thread_params *p, const int esize)
306759cf9b5SJoyce Kong {
307759cf9b5SJoyce Kong uint64_t time_diff = 0;
308759cf9b5SJoyce Kong uint64_t begin = 0;
309759cf9b5SJoyce Kong uint64_t hz = rte_get_timer_hz();
310759cf9b5SJoyce Kong uint64_t lcount = 0;
311759cf9b5SJoyce Kong const unsigned int lcore = rte_lcore_id();
312*a4cb5461SPaul Szczepanek struct ring_params *ring_params = p->ring_params;
3131fa5d009SHonnappa Nagarahalli void *burst = NULL;
3141fa5d009SHonnappa Nagarahalli
3151fa5d009SHonnappa Nagarahalli burst = test_ring_calloc(MAX_BURST, esize);
3161fa5d009SHonnappa Nagarahalli if (burst == NULL)
3171fa5d009SHonnappa Nagarahalli return -1;
318759cf9b5SJoyce Kong
319cb056611SStephen Hemminger /* wait synchro for workers */
320cb056611SStephen Hemminger if (lcore != rte_get_main_lcore())
321b6a7e685STyler Retzlaff rte_wait_until_equal_32((uint32_t *)(uintptr_t)&synchro, 1,
322b6a7e685STyler Retzlaff rte_memory_order_relaxed);
323759cf9b5SJoyce Kong
324759cf9b5SJoyce Kong begin = rte_get_timer_cycles();
325759cf9b5SJoyce Kong while (time_diff < hz * TIME_MS / 1000) {
326*a4cb5461SPaul Szczepanek test_ring_enqueue(ring_params->r, burst, esize,
327*a4cb5461SPaul Szczepanek ring_params->elem_size,
3281fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK);
329*a4cb5461SPaul Szczepanek test_ring_dequeue(ring_params->r, burst, esize,
330*a4cb5461SPaul Szczepanek ring_params->elem_size,
3311fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK);
332759cf9b5SJoyce Kong lcount++;
333759cf9b5SJoyce Kong time_diff = rte_get_timer_cycles() - begin;
334759cf9b5SJoyce Kong }
335759cf9b5SJoyce Kong queue_count[lcore] = lcount;
3361fa5d009SHonnappa Nagarahalli
3371fa5d009SHonnappa Nagarahalli rte_free(burst);
3381fa5d009SHonnappa Nagarahalli
339759cf9b5SJoyce Kong return 0;
340759cf9b5SJoyce Kong }
341759cf9b5SJoyce Kong
342759cf9b5SJoyce Kong static int
load_loop_fn(void * p)3431fa5d009SHonnappa Nagarahalli load_loop_fn(void *p)
3441fa5d009SHonnappa Nagarahalli {
3451fa5d009SHonnappa Nagarahalli struct thread_params *params = p;
3461fa5d009SHonnappa Nagarahalli
3471fa5d009SHonnappa Nagarahalli return load_loop_fn_helper(params, -1);
3481fa5d009SHonnappa Nagarahalli }
3491fa5d009SHonnappa Nagarahalli
3501fa5d009SHonnappa Nagarahalli static int
load_loop_fn_16B(void * p)3511fa5d009SHonnappa Nagarahalli load_loop_fn_16B(void *p)
3521fa5d009SHonnappa Nagarahalli {
3531fa5d009SHonnappa Nagarahalli struct thread_params *params = p;
3541fa5d009SHonnappa Nagarahalli
3551fa5d009SHonnappa Nagarahalli return load_loop_fn_helper(params, 16);
3561fa5d009SHonnappa Nagarahalli }
3571fa5d009SHonnappa Nagarahalli
3581fa5d009SHonnappa Nagarahalli static int
run_on_all_cores(struct rte_ring * r,const int esize)3591fa5d009SHonnappa Nagarahalli run_on_all_cores(struct rte_ring *r, const int esize)
360759cf9b5SJoyce Kong {
36150959a89SFeifei Wang uint64_t total;
362*a4cb5461SPaul Szczepanek struct ring_params ring_params = {0};
363*a4cb5461SPaul Szczepanek struct thread_params params = { .ring_params = &ring_params };
3641fa5d009SHonnappa Nagarahalli lcore_function_t *lcore_f;
365759cf9b5SJoyce Kong unsigned int i, c;
366759cf9b5SJoyce Kong
3671fa5d009SHonnappa Nagarahalli if (esize == -1)
3681fa5d009SHonnappa Nagarahalli lcore_f = load_loop_fn;
3691fa5d009SHonnappa Nagarahalli else
3701fa5d009SHonnappa Nagarahalli lcore_f = load_loop_fn_16B;
3711fa5d009SHonnappa Nagarahalli
372759cf9b5SJoyce Kong for (i = 0; i < RTE_DIM(bulk_sizes); i++) {
37350959a89SFeifei Wang total = 0;
374759cf9b5SJoyce Kong printf("\nBulk enq/dequeue count on size %u\n", bulk_sizes[i]);
375*a4cb5461SPaul Szczepanek params.ring_params->bulk_sizes_i = i;
376*a4cb5461SPaul Szczepanek params.ring_params->r = r;
377759cf9b5SJoyce Kong
378cb056611SStephen Hemminger /* clear synchro and start workers */
379b6a7e685STyler Retzlaff rte_atomic_store_explicit(&synchro, 0, rte_memory_order_relaxed);
380*a4cb5461SPaul Szczepanek if (rte_eal_mp_remote_launch(lcore_f, ¶ms, SKIP_MAIN) < 0)
381759cf9b5SJoyce Kong return -1;
382759cf9b5SJoyce Kong
383cb056611SStephen Hemminger /* start synchro and launch test on main */
384b6a7e685STyler Retzlaff rte_atomic_store_explicit(&synchro, 1, rte_memory_order_relaxed);
385*a4cb5461SPaul Szczepanek lcore_f(¶ms);
386759cf9b5SJoyce Kong
387759cf9b5SJoyce Kong rte_eal_mp_wait_lcore();
388759cf9b5SJoyce Kong
389759cf9b5SJoyce Kong RTE_LCORE_FOREACH(c) {
390759cf9b5SJoyce Kong printf("Core [%u] count = %"PRIu64"\n",
391759cf9b5SJoyce Kong c, queue_count[c]);
392759cf9b5SJoyce Kong total += queue_count[c];
393759cf9b5SJoyce Kong }
394759cf9b5SJoyce Kong
395759cf9b5SJoyce Kong printf("Total count (size: %u): %"PRIu64"\n",
396759cf9b5SJoyce Kong bulk_sizes[i], total);
397759cf9b5SJoyce Kong }
398759cf9b5SJoyce Kong
399759cf9b5SJoyce Kong return 0;
400759cf9b5SJoyce Kong }
401759cf9b5SJoyce Kong
402a9de470cSBruce Richardson /*
403a9de470cSBruce Richardson * Test function that determines how long an enqueue + dequeue of a single item
404a9de470cSBruce Richardson * takes on a single lcore. Result is for comparison with the bulk enq+deq.
405a9de470cSBruce Richardson */
4061fa5d009SHonnappa Nagarahalli static int
test_single_enqueue_dequeue(struct rte_ring * r,const int esize,const unsigned int api_type)4071fa5d009SHonnappa Nagarahalli test_single_enqueue_dequeue(struct rte_ring *r, const int esize,
4081fa5d009SHonnappa Nagarahalli const unsigned int api_type)
409a9de470cSBruce Richardson {
4101fa5d009SHonnappa Nagarahalli const unsigned int iter_shift = 24;
4111fa5d009SHonnappa Nagarahalli const unsigned int iterations = 1 << iter_shift;
4121fa5d009SHonnappa Nagarahalli unsigned int i = 0;
413a9de470cSBruce Richardson void *burst = NULL;
414a9de470cSBruce Richardson
4151fa5d009SHonnappa Nagarahalli /* alloc dummy object pointers */
4161fa5d009SHonnappa Nagarahalli burst = test_ring_calloc(1, esize);
4171fa5d009SHonnappa Nagarahalli if (burst == NULL)
4181fa5d009SHonnappa Nagarahalli return -1;
419a9de470cSBruce Richardson
4201fa5d009SHonnappa Nagarahalli const uint64_t start = rte_rdtsc();
421a9de470cSBruce Richardson for (i = 0; i < iterations; i++) {
4221fa5d009SHonnappa Nagarahalli test_ring_enqueue(r, burst, esize, 1, api_type);
4231fa5d009SHonnappa Nagarahalli test_ring_dequeue(r, burst, esize, 1, api_type);
424a9de470cSBruce Richardson }
4251fa5d009SHonnappa Nagarahalli const uint64_t end = rte_rdtsc();
426a9de470cSBruce Richardson
4271fa5d009SHonnappa Nagarahalli test_ring_print_test_string(api_type, esize, 1,
4281fa5d009SHonnappa Nagarahalli ((double)(end - start)) / iterations);
4291fa5d009SHonnappa Nagarahalli
4301fa5d009SHonnappa Nagarahalli rte_free(burst);
4311fa5d009SHonnappa Nagarahalli
4321fa5d009SHonnappa Nagarahalli return 0;
433a9de470cSBruce Richardson }
434a9de470cSBruce Richardson
435a9de470cSBruce Richardson /*
4361fa5d009SHonnappa Nagarahalli * Test that does both enqueue and dequeue on a core using the burst/bulk API
4371fa5d009SHonnappa Nagarahalli * calls Results should be the same as for the bulk function called on a
4381fa5d009SHonnappa Nagarahalli * single lcore.
439a9de470cSBruce Richardson */
4401fa5d009SHonnappa Nagarahalli static int
test_burst_bulk_enqueue_dequeue(struct rte_ring * r,const int esize,const unsigned int api_type)4411fa5d009SHonnappa Nagarahalli test_burst_bulk_enqueue_dequeue(struct rte_ring *r, const int esize,
4421fa5d009SHonnappa Nagarahalli const unsigned int api_type)
443a9de470cSBruce Richardson {
444*a4cb5461SPaul Szczepanek const unsigned int iter_shift = 26;
4451fa5d009SHonnappa Nagarahalli const unsigned int iterations = 1 << iter_shift;
446*a4cb5461SPaul Szczepanek unsigned int sz, i;
4471fa5d009SHonnappa Nagarahalli void **burst = NULL;
448a9de470cSBruce Richardson
4491fa5d009SHonnappa Nagarahalli burst = test_ring_calloc(MAX_BURST, esize);
4501fa5d009SHonnappa Nagarahalli if (burst == NULL)
4511fa5d009SHonnappa Nagarahalli return -1;
4521fa5d009SHonnappa Nagarahalli
4531fa5d009SHonnappa Nagarahalli for (sz = 0; sz < RTE_DIM(bulk_sizes); sz++) {
454*a4cb5461SPaul Szczepanek const unsigned int n = iterations / bulk_sizes[sz];
4551fa5d009SHonnappa Nagarahalli const uint64_t start = rte_rdtsc();
456*a4cb5461SPaul Szczepanek for (i = 0; i < n; i++) {
4571fa5d009SHonnappa Nagarahalli test_ring_enqueue(r, burst, esize, bulk_sizes[sz],
4581fa5d009SHonnappa Nagarahalli api_type);
4591fa5d009SHonnappa Nagarahalli test_ring_dequeue(r, burst, esize, bulk_sizes[sz],
4601fa5d009SHonnappa Nagarahalli api_type);
461a9de470cSBruce Richardson }
4621fa5d009SHonnappa Nagarahalli const uint64_t end = rte_rdtsc();
463a9de470cSBruce Richardson
4641fa5d009SHonnappa Nagarahalli test_ring_print_test_string(api_type, esize, bulk_sizes[sz],
465*a4cb5461SPaul Szczepanek ((double)end - start) / iterations);
466a9de470cSBruce Richardson }
467a9de470cSBruce Richardson
4681fa5d009SHonnappa Nagarahalli rte_free(burst);
4691fa5d009SHonnappa Nagarahalli
4701fa5d009SHonnappa Nagarahalli return 0;
4711fa5d009SHonnappa Nagarahalli }
4721fa5d009SHonnappa Nagarahalli
473*a4cb5461SPaul Szczepanek static __rte_always_inline int
test_ring_perf_esize_run_on_two_cores(struct thread_params * param1,struct thread_params * param2)474*a4cb5461SPaul Szczepanek test_ring_perf_esize_run_on_two_cores(
475*a4cb5461SPaul Szczepanek struct thread_params *param1, struct thread_params *param2)
476*a4cb5461SPaul Szczepanek {
477*a4cb5461SPaul Szczepanek struct lcore_pair cores;
478*a4cb5461SPaul Szczepanek
479*a4cb5461SPaul Szczepanek if (get_two_hyperthreads(&cores) == 0) {
480*a4cb5461SPaul Szczepanek printf("\n### Testing using two hyperthreads ###\n");
481*a4cb5461SPaul Szczepanek if (run_on_core_pair(&cores, param1, param2) < 0)
482*a4cb5461SPaul Szczepanek return -1;
483*a4cb5461SPaul Szczepanek }
484*a4cb5461SPaul Szczepanek if (get_two_cores(&cores) == 0) {
485*a4cb5461SPaul Szczepanek printf("\n### Testing using two physical cores ###\n");
486*a4cb5461SPaul Szczepanek if (run_on_core_pair(&cores, param1, param2) < 0)
487*a4cb5461SPaul Szczepanek return -1;
488*a4cb5461SPaul Szczepanek }
489*a4cb5461SPaul Szczepanek if (get_two_sockets(&cores) == 0) {
490*a4cb5461SPaul Szczepanek printf("\n### Testing using two NUMA nodes ###\n");
491*a4cb5461SPaul Szczepanek if (run_on_core_pair(&cores, param1, param2) < 0)
492*a4cb5461SPaul Szczepanek return -1;
493*a4cb5461SPaul Szczepanek }
494*a4cb5461SPaul Szczepanek return 0;
495*a4cb5461SPaul Szczepanek }
496*a4cb5461SPaul Szczepanek
4971fa5d009SHonnappa Nagarahalli /* Run all tests for a given element size */
4981fa5d009SHonnappa Nagarahalli static __rte_always_inline int
test_ring_perf_esize(const int esize)4991fa5d009SHonnappa Nagarahalli test_ring_perf_esize(const int esize)
500a9de470cSBruce Richardson {
5011fa5d009SHonnappa Nagarahalli struct rte_ring *r = NULL;
502*a4cb5461SPaul Szczepanek double results_enq[RTE_DIM(bulk_sizes)];
503*a4cb5461SPaul Szczepanek double results_deq[RTE_DIM(bulk_sizes)];
504*a4cb5461SPaul Szczepanek struct ring_params ring_params = {
505*a4cb5461SPaul Szczepanek .elem_size = esize, .ring_flags = TEST_RING_ELEM_BULK };
506*a4cb5461SPaul Szczepanek struct thread_params param1 = {
507*a4cb5461SPaul Szczepanek .ring_params = &ring_params, .results = results_enq };
508*a4cb5461SPaul Szczepanek struct thread_params param2 = {
509*a4cb5461SPaul Szczepanek .ring_params = &ring_params, .results = results_deq };
510a9de470cSBruce Richardson
5111fa5d009SHonnappa Nagarahalli /*
5121fa5d009SHonnappa Nagarahalli * Performance test for legacy/_elem APIs
5131fa5d009SHonnappa Nagarahalli * SP-SC/MP-MC, single
5141fa5d009SHonnappa Nagarahalli */
5151fa5d009SHonnappa Nagarahalli r = test_ring_create(RING_NAME, esize, RING_SIZE, rte_socket_id(), 0);
5161fa5d009SHonnappa Nagarahalli if (r == NULL)
5171fa5d009SHonnappa Nagarahalli goto test_fail;
5181fa5d009SHonnappa Nagarahalli
5191fa5d009SHonnappa Nagarahalli printf("\n### Testing single element enq/deq ###\n");
5201fa5d009SHonnappa Nagarahalli if (test_single_enqueue_dequeue(r, esize,
5211fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_SPSC | TEST_RING_ELEM_SINGLE) < 0)
5221fa5d009SHonnappa Nagarahalli goto test_fail;
5231fa5d009SHonnappa Nagarahalli if (test_single_enqueue_dequeue(r, esize,
5241fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_SINGLE) < 0)
5251fa5d009SHonnappa Nagarahalli goto test_fail;
5261fa5d009SHonnappa Nagarahalli
5271fa5d009SHonnappa Nagarahalli printf("\n### Testing burst enq/deq ###\n");
5281fa5d009SHonnappa Nagarahalli if (test_burst_bulk_enqueue_dequeue(r, esize,
5291fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BURST) < 0)
5301fa5d009SHonnappa Nagarahalli goto test_fail;
5311fa5d009SHonnappa Nagarahalli if (test_burst_bulk_enqueue_dequeue(r, esize,
5321fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BURST) < 0)
5331fa5d009SHonnappa Nagarahalli goto test_fail;
5341fa5d009SHonnappa Nagarahalli
5351fa5d009SHonnappa Nagarahalli printf("\n### Testing bulk enq/deq ###\n");
5361fa5d009SHonnappa Nagarahalli if (test_burst_bulk_enqueue_dequeue(r, esize,
5371fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK) < 0)
5381fa5d009SHonnappa Nagarahalli goto test_fail;
5391fa5d009SHonnappa Nagarahalli if (test_burst_bulk_enqueue_dequeue(r, esize,
5401fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK) < 0)
5411fa5d009SHonnappa Nagarahalli goto test_fail;
5421fa5d009SHonnappa Nagarahalli
5431fa5d009SHonnappa Nagarahalli printf("\n### Testing empty bulk deq ###\n");
5441fa5d009SHonnappa Nagarahalli test_empty_dequeue(r, esize,
5451fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK);
5461fa5d009SHonnappa Nagarahalli test_empty_dequeue(r, esize,
5471fa5d009SHonnappa Nagarahalli TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK);
5481fa5d009SHonnappa Nagarahalli
549*a4cb5461SPaul Szczepanek ring_params.r = r;
550a9de470cSBruce Richardson
551*a4cb5461SPaul Szczepanek ring_params.ring_flags = TEST_RING_THREAD_SPSC | TEST_RING_ELEM_BULK;
552*a4cb5461SPaul Szczepanek test_ring_perf_esize_run_on_two_cores(¶m1, ¶m2);
553*a4cb5461SPaul Szczepanek
554*a4cb5461SPaul Szczepanek ring_params.ring_flags = TEST_RING_THREAD_MPMC | TEST_RING_ELEM_BULK;
555*a4cb5461SPaul Szczepanek test_ring_perf_esize_run_on_two_cores(¶m1, ¶m2);
5561fa5d009SHonnappa Nagarahalli
557cb056611SStephen Hemminger printf("\n### Testing using all worker nodes ###\n");
5581fa5d009SHonnappa Nagarahalli if (run_on_all_cores(r, esize) < 0)
5591fa5d009SHonnappa Nagarahalli goto test_fail;
5601fa5d009SHonnappa Nagarahalli
5611fa5d009SHonnappa Nagarahalli rte_ring_free(r);
5621fa5d009SHonnappa Nagarahalli
5631fa5d009SHonnappa Nagarahalli return 0;
5641fa5d009SHonnappa Nagarahalli
5651fa5d009SHonnappa Nagarahalli test_fail:
5661fa5d009SHonnappa Nagarahalli rte_ring_free(r);
5671fa5d009SHonnappa Nagarahalli
5681fa5d009SHonnappa Nagarahalli return -1;
569a9de470cSBruce Richardson }
570a9de470cSBruce Richardson
571*a4cb5461SPaul Szczepanek
572*a4cb5461SPaul Szczepanek static __rte_always_inline int
test_ring_perf_compression(void)573*a4cb5461SPaul Szczepanek test_ring_perf_compression(void)
574*a4cb5461SPaul Szczepanek {
575*a4cb5461SPaul Szczepanek double results1[RTE_DIM(bulk_sizes)];
576*a4cb5461SPaul Szczepanek double results2[RTE_DIM(bulk_sizes)];
577*a4cb5461SPaul Szczepanek double results1_comp[2][RTE_DIM(bulk_sizes)];
578*a4cb5461SPaul Szczepanek double results2_comp[2][RTE_DIM(bulk_sizes)];
579*a4cb5461SPaul Szczepanek
580*a4cb5461SPaul Szczepanek struct lcore_pair cores;
581*a4cb5461SPaul Szczepanek int ret = -1;
582*a4cb5461SPaul Szczepanek unsigned int i, j;
583*a4cb5461SPaul Szczepanek struct ring_params ring_params = { .elem_size = sizeof(void *) };
584*a4cb5461SPaul Szczepanek struct thread_params param1 = {
585*a4cb5461SPaul Szczepanek .ring_params = &ring_params, .results = results1 };
586*a4cb5461SPaul Szczepanek struct thread_params param2 = {
587*a4cb5461SPaul Szczepanek .ring_params = &ring_params, .results = results2 };
588*a4cb5461SPaul Szczepanek
589*a4cb5461SPaul Szczepanek printf("\n### Testing compression gain ###");
590*a4cb5461SPaul Szczepanek
591*a4cb5461SPaul Szczepanek ring_params.r = rte_ring_create_elem(
592*a4cb5461SPaul Szczepanek RING_NAME, sizeof(void *),
593*a4cb5461SPaul Szczepanek RING_SIZE, rte_socket_id(),
594*a4cb5461SPaul Szczepanek RING_F_SP_ENQ | RING_F_SC_DEQ);
595*a4cb5461SPaul Szczepanek
596*a4cb5461SPaul Szczepanek if (ring_params.r == NULL)
597*a4cb5461SPaul Szczepanek return -1;
598*a4cb5461SPaul Szczepanek
599*a4cb5461SPaul Szczepanek if (get_two_cores(&cores) == 0) {
600*a4cb5461SPaul Szczepanek printf("\n### Testing zero copy ###\n");
601*a4cb5461SPaul Szczepanek ring_params.ring_flags = TEST_RING_ELEM_BURST_ZC;
602*a4cb5461SPaul Szczepanek ret = run_on_core_pair(&cores, ¶m1, ¶m2);
603*a4cb5461SPaul Szczepanek }
604*a4cb5461SPaul Szczepanek
605*a4cb5461SPaul Szczepanek rte_ring_free(ring_params.r);
606*a4cb5461SPaul Szczepanek
607*a4cb5461SPaul Szczepanek if (ret != 0)
608*a4cb5461SPaul Szczepanek return ret;
609*a4cb5461SPaul Szczepanek
610*a4cb5461SPaul Szczepanek /* rings allow only multiples of 4 as sizes,
611*a4cb5461SPaul Szczepanek * we allocate size 4 despite only using 2 bytes
612*a4cb5461SPaul Szczepanek * and use half of RING_SIZE as the number of elements
613*a4cb5461SPaul Szczepanek */
614*a4cb5461SPaul Szczepanek ring_params.r = rte_ring_create_elem(
615*a4cb5461SPaul Szczepanek RING_NAME, sizeof(uint32_t),
616*a4cb5461SPaul Szczepanek RING_SIZE / 2, rte_socket_id(),
617*a4cb5461SPaul Szczepanek RING_F_SP_ENQ | RING_F_SC_DEQ);
618*a4cb5461SPaul Szczepanek
619*a4cb5461SPaul Szczepanek if (ring_params.r == NULL)
620*a4cb5461SPaul Szczepanek return -1;
621*a4cb5461SPaul Szczepanek
622*a4cb5461SPaul Szczepanek param1.results = results1_comp[0];
623*a4cb5461SPaul Szczepanek param2.results = results2_comp[0];
624*a4cb5461SPaul Szczepanek
625*a4cb5461SPaul Szczepanek if (get_two_cores(&cores) == 0) {
626*a4cb5461SPaul Szczepanek printf("\n### Testing zero copy with compression (16b) ###\n");
627*a4cb5461SPaul Szczepanek ring_params.ring_flags =
628*a4cb5461SPaul Szczepanek TEST_RING_ELEM_BURST_ZC_COMPRESS_PTR_16;
629*a4cb5461SPaul Szczepanek ret = run_on_core_pair(&cores, ¶m1, ¶m2);
630*a4cb5461SPaul Szczepanek }
631*a4cb5461SPaul Szczepanek
632*a4cb5461SPaul Szczepanek rte_ring_free(ring_params.r);
633*a4cb5461SPaul Szczepanek
634*a4cb5461SPaul Szczepanek if (ret != 0)
635*a4cb5461SPaul Szczepanek return ret;
636*a4cb5461SPaul Szczepanek
637*a4cb5461SPaul Szczepanek ring_params.r = rte_ring_create_elem(
638*a4cb5461SPaul Szczepanek RING_NAME, sizeof(uint32_t),
639*a4cb5461SPaul Szczepanek RING_SIZE, rte_socket_id(),
640*a4cb5461SPaul Szczepanek RING_F_SP_ENQ | RING_F_SC_DEQ);
641*a4cb5461SPaul Szczepanek
642*a4cb5461SPaul Szczepanek if (ring_params.r == NULL)
643*a4cb5461SPaul Szczepanek return -1;
644*a4cb5461SPaul Szczepanek
645*a4cb5461SPaul Szczepanek param1.results = results1_comp[1];
646*a4cb5461SPaul Szczepanek param2.results = results2_comp[1];
647*a4cb5461SPaul Szczepanek
648*a4cb5461SPaul Szczepanek if (get_two_cores(&cores) == 0) {
649*a4cb5461SPaul Szczepanek printf("\n### Testing zero copy with compression (32b) ###\n");
650*a4cb5461SPaul Szczepanek ring_params.ring_flags =
651*a4cb5461SPaul Szczepanek TEST_RING_ELEM_BURST_ZC_COMPRESS_PTR_32;
652*a4cb5461SPaul Szczepanek ret = run_on_core_pair(&cores, ¶m1, ¶m2);
653*a4cb5461SPaul Szczepanek }
654*a4cb5461SPaul Szczepanek
655*a4cb5461SPaul Szczepanek rte_ring_free(ring_params.r);
656*a4cb5461SPaul Szczepanek
657*a4cb5461SPaul Szczepanek for (j = 0; j < 2; j++) {
658*a4cb5461SPaul Szczepanek printf("\n### Potential gain from compression (%d-bit offsets) "
659*a4cb5461SPaul Szczepanek "###\n", (j + 1) * 16);
660*a4cb5461SPaul Szczepanek for (i = 0; i < RTE_DIM(bulk_sizes); i++) {
661*a4cb5461SPaul Szczepanek const double result = results1[i] + results2[i];
662*a4cb5461SPaul Szczepanek const double result_comp = results1_comp[j][i] +
663*a4cb5461SPaul Szczepanek results2_comp[j][i];
664*a4cb5461SPaul Szczepanek const double gain = 100 - (result_comp / result) * 100;
665*a4cb5461SPaul Szczepanek
666*a4cb5461SPaul Szczepanek printf("Gain of %5.1F%% for burst of %-3u elems\n",
667*a4cb5461SPaul Szczepanek gain, bulk_sizes[i]);
668*a4cb5461SPaul Szczepanek }
669*a4cb5461SPaul Szczepanek }
670*a4cb5461SPaul Szczepanek
671*a4cb5461SPaul Szczepanek return ret;
672*a4cb5461SPaul Szczepanek }
673*a4cb5461SPaul Szczepanek
674a9de470cSBruce Richardson static int
test_ring_perf(void)675a9de470cSBruce Richardson test_ring_perf(void)
676a9de470cSBruce Richardson {
6771fa5d009SHonnappa Nagarahalli /* Run all the tests for different element sizes */
6781fa5d009SHonnappa Nagarahalli if (test_ring_perf_esize(-1) == -1)
679a9de470cSBruce Richardson return -1;
680a9de470cSBruce Richardson
6811fa5d009SHonnappa Nagarahalli if (test_ring_perf_esize(16) == -1)
6821fa5d009SHonnappa Nagarahalli return -1;
683a9de470cSBruce Richardson
684*a4cb5461SPaul Szczepanek /* Test for performance gain of compression */
685*a4cb5461SPaul Szczepanek if (test_ring_perf_compression() == -1)
686*a4cb5461SPaul Szczepanek return -1;
687*a4cb5461SPaul Szczepanek
688a9de470cSBruce Richardson return 0;
689a9de470cSBruce Richardson }
690a9de470cSBruce Richardson
691e0a8442cSBruce Richardson REGISTER_PERF_TEST(ring_perf_autotest, test_ring_perf);
692