DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC PATCH] eal: rte_rand yields only 62 random bits
@ 2015-03-17 16:18 Robert Sanford
  2015-03-27 16:38 ` Sanford, Robert
  0 siblings, 1 reply; 9+ messages in thread
From: Robert Sanford @ 2015-03-17 16:18 UTC (permalink / raw)
  To: David.Marchand, Bruce.Richardson, dev

The implementation of rte_rand() returns only 62 bits of 
pseudo-randomness, because the underlying calls to lrand48()
"return non-negative long integers uniformly distributed
between 0 and 2^31."

We have written a potential fix, but before we spend more
time testing and refining it, I wanted to check with you
guys.

We switched to using the reentrant versions of [ls]rand48,
and maintain per-lcore state. We need ~2.06 calls to
lrand48_r(), per call to rte_rand().

Do you agree with the approach we've taken in this patch?


Thanks,
Robert

---
 lib/librte_eal/common/include/rte_random.h |   33 +++++++++++++++++++++++++--
 lib/librte_eal/linuxapp/eal/eal_thread.c   |    7 ++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_random.h b/lib/librte_eal/common/include/rte_random.h
index 24ae836..b9248cd 100644
--- a/lib/librte_eal/common/include/rte_random.h
+++ b/lib/librte_eal/common/include/rte_random.h
@@ -46,6 +46,17 @@ extern "C" {
 
 #include <stdint.h>
 #include <stdlib.h>
+#include <rte_per_lcore.h>
+#include <rte_branch_prediction.h>
+
+struct rte_rand_data {
+	struct drand48_data _dr48;
+	uint32_t _hi_bits;
+	uint8_t _bits_left;
+};
+
+RTE_DECLARE_PER_LCORE(struct rte_rand_data, _rand_data);
+
 
 /**
  * Seed the pseudo-random generator.
@@ -60,7 +71,7 @@ extern "C" {
 static inline void
 rte_srand(uint64_t seedval)
 {
-	srand48((long unsigned int)seedval);
+	srand48_r((long unsigned int)seedval, &RTE_PER_LCORE(_rand_data)._dr48);
 }
 
 /**
@@ -76,10 +87,26 @@ rte_srand(uint64_t seedval)
 static inline uint64_t
 rte_rand(void)
 {
+	struct rte_rand_data *rd = &RTE_PER_LCORE(_rand_data);
 	uint64_t val;
-	val = lrand48();
+	uint32_t hi_bits;
+	long int result;
+
+	if (unlikely(rd->_bits_left < 2)) {
+		lrand48_r(&rd->_dr48, &result);
+		rd->_hi_bits |= (uint32_t)result << (1 - rd->_bits_left);
+		rd->_bits_left += 31;
+	}
+
+	hi_bits = rd->_hi_bits;
+	lrand48_r(&rd->_dr48, &result);
+	val = (uint32_t)result | (hi_bits & 0x8000000);
 	val <<= 32;
-	val += lrand48();
+	hi_bits <<= 1;
+	lrand48_r(&rd->_dr48, &result);
+	val |= (uint32_t)result | (hi_bits & 0x8000000);
+	rd->_hi_bits = hi_bits << 1;
+	rd->_bits_left -= 2;
 	return val;
 }
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_thread.c b/lib/librte_eal/linuxapp/eal/eal_thread.c
index 5635c7d..08e7f72 100644
--- a/lib/librte_eal/linuxapp/eal/eal_thread.c
+++ b/lib/librte_eal/linuxapp/eal/eal_thread.c
@@ -52,6 +52,8 @@
 #include <rte_eal.h>
 #include <rte_per_lcore.h>
 #include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_random.h>
 
 #include "eal_private.h"
 #include "eal_thread.h"
@@ -59,6 +61,8 @@
 RTE_DEFINE_PER_LCORE(unsigned, _lcore_id) = LCORE_ID_ANY;
 RTE_DEFINE_PER_LCORE(unsigned, _socket_id) = (unsigned)SOCKET_ID_ANY;
 RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset);
+RTE_DEFINE_PER_LCORE(struct rte_rand_data, _rand_data);
+
 
 /*
  * Send a message to a slave lcore identified by slave_id to call a
@@ -147,6 +151,9 @@ eal_thread_loop(__attribute__((unused)) void *arg)
 	/* set the lcore ID in per-lcore memory area */
 	RTE_PER_LCORE(_lcore_id) = lcore_id;
 
+	/* seed per-lcore PRNG */
+	rte_srand(rte_rdtsc());
+
 	/* set CPU affinity */
 	if (eal_thread_set_affinity() < 0)
 		rte_panic("cannot set affinity\n");
-- 
1.7.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-04-01  2:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-17 16:18 [dpdk-dev] [RFC PATCH] eal: rte_rand yields only 62 random bits Robert Sanford
2015-03-27 16:38 ` Sanford, Robert
2015-03-28  0:02   ` Stephen Hemminger
2015-03-28  0:03   ` Stephen Hemminger
2015-03-28  0:38     ` Matthew Hall
2015-03-30  5:28       ` Stephen Hemminger
2015-03-30 22:19         ` Robert Sanford
2015-03-31  1:51           ` Neil Horman
2015-04-01  2:17             ` Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).