From patchwork Tue Mar 17 16:18:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Sanford X-Patchwork-Id: 4035 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 61DC49AA8; Tue, 17 Mar 2015 17:18:10 +0100 (CET) Received: from mail-ig0-f172.google.com (mail-ig0-f172.google.com [209.85.213.172]) by dpdk.org (Postfix) with ESMTP id 106D89AA1 for ; Tue, 17 Mar 2015 17:18:09 +0100 (CET) Received: by igbue6 with SMTP id ue6so16908177igb.1 for ; Tue, 17 Mar 2015 09:18:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id; bh=CCtbm/jjPQnAgL6mkI9qyovSfKBmYWxLHtDzKT4drtA=; b=MLswc1flHB6qoZXDSBgyhp/pUVYmqz87Fad1aL56KWsxKNOIklLvDXYfLn/2FHgFiU raaXzG94jrENfUV5+cKdOW4xFG6ml6kM27ShkU+Drs1Q6eKBpsRqhAZ45SZmYUYpaHLP RmFPnmREHnLiFsS97x1qtgqvTLr4Gy3sFxpKPz6FM07ixy2ZmIhCVwyKZp5aKRFDMOgC LoQyUCtqr0MgG6U+5O7ocfOdhQ6a4jwev0u+4GbAQJqOykTc7FMJ3czm8Ryll7wyGS5p 9nUyCi2OyYqHLWSHjmxP8j13tAOx/AIH9K9OKxQSUeQ7t2QIaeFjqr17i18mpzUGc0PZ K8XA== X-Received: by 10.50.30.130 with SMTP id s2mr121450263igh.11.1426609088384; Tue, 17 Mar 2015 09:18:08 -0700 (PDT) Received: from localhost.localdomain ([23.79.237.14]) by mx.google.com with ESMTPSA id x10sm1359998igl.13.2015.03.17.09.18.06 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Mar 2015 09:18:07 -0700 (PDT) From: Robert Sanford X-Google-Original-From: Robert Sanford To: David.Marchand@6wind.com, Bruce.Richardson@intel.com, dev@dpdk.org Date: Tue, 17 Mar 2015 12:18:01 -0400 Message-Id: <1426609081-47774-1-git-send-email-rsanford@akamai.com> X-Mailer: git-send-email 1.7.1 Subject: [dpdk-dev] [RFC PATCH] eal: rte_rand yields only 62 random bits X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "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 #include +#include +#include + +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 #include #include +#include +#include #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");