3f002f0696
This commit replaces rte_rand()'s use of lrand48() with a DPDK-native combined Linear Feedback Shift Register (LFSR) (also known as Tausworthe) pseudo-random number generator. This generator is faster and produces better-quality random numbers than the linear congruential generator (LCG) of lib's lrand48(). The implementation, as opposed to lrand48(), is multi-thread safe in regards to concurrent rte_rand() calls from different lcore threads. A LCG is still used, but only to seed the five per-lcore LFSR sequences. In addition, this patch also addresses the issue of the legacy implementation only producing 62 bits of pseudo randomness, while the API requires all 64 bits to be random. This pseudo-random number generator is not cryptographically secure - just like lrand48(). Bugzilla ID: 114 Bugzilla ID: 276 Signed-off-by: Mattias Rönnblom <mattias.ronnblom@ericsson.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
76 lines
1.2 KiB
C
76 lines
1.2 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(c) 2019 Ericsson AB
|
|
*/
|
|
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
|
|
#include <rte_common.h>
|
|
#include <rte_cycles.h>
|
|
#include <rte_random.h>
|
|
|
|
#include "test.h"
|
|
|
|
static volatile uint64_t vsum;
|
|
|
|
#define ITERATIONS (100000000)
|
|
|
|
enum rand_type {
|
|
rand_type_64
|
|
};
|
|
|
|
static const char *
|
|
rand_type_desc(enum rand_type rand_type)
|
|
{
|
|
switch (rand_type) {
|
|
case rand_type_64:
|
|
return "Full 64-bit [rte_rand()]";
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static __rte_always_inline void
|
|
test_rand_perf_type(enum rand_type rand_type)
|
|
{
|
|
uint64_t start;
|
|
uint32_t i;
|
|
uint64_t end;
|
|
uint64_t sum = 0;
|
|
uint64_t op_latency;
|
|
|
|
start = rte_rdtsc();
|
|
|
|
for (i = 0; i < ITERATIONS; i++) {
|
|
switch (rand_type) {
|
|
case rand_type_64:
|
|
sum += rte_rand();
|
|
break;
|
|
}
|
|
}
|
|
|
|
end = rte_rdtsc();
|
|
|
|
/* to avoid an optimizing compiler removing the whole loop */
|
|
vsum = sum;
|
|
|
|
op_latency = (end - start) / ITERATIONS;
|
|
|
|
printf("%s: %"PRId64" TSC cycles/op\n", rand_type_desc(rand_type),
|
|
op_latency);
|
|
}
|
|
|
|
static int
|
|
test_rand_perf(void)
|
|
{
|
|
rte_srand(42);
|
|
|
|
printf("Pseudo-random number generation latencies:\n");
|
|
|
|
test_rand_perf_type(rand_type_64);
|
|
|
|
return 0;
|
|
}
|
|
|
|
REGISTER_TEST_COMMAND(rand_perf_autotest, test_rand_perf);
|