From patchwork Fri Apr 19 21:21:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Mattias_R=C3=B6nnblom?= X-Patchwork-Id: 52969 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DD8D21BC1E; Fri, 19 Apr 2019 23:21:51 +0200 (CEST) Received: from sessmg22.ericsson.net (sessmg22.ericsson.net [193.180.251.58]) by dpdk.org (Postfix) with ESMTP id 112321B9F4 for ; Fri, 19 Apr 2019 23:21:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; d=ericsson.com; s=mailgw201801; c=relaxed/relaxed; q=dns/txt; i=@ericsson.com; t=1555708903; x=1558300903; h=From:Sender:Reply-To:Subject:Date:Message-ID:To:CC:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=AZMr17hUDMSFSFosfhXXmhcc03TFfuonSl11POW/700=; b=PS8LDz6VjXjQ6PL9HBAy+4nvHAn0aLh61ZDgUVZtNqmC/+m6EogtgbQT+dhoZIT0 OrWbjBlmfQT1RNheTALkz4P5gcMC9Pb4NQbhTbwIiLbZZzVhtw2g/ez9yBz7lUfV zQ+5KIZrUPqpfFddc4jPpaUqmsr7cwgRF1O/mfIbu5E=; X-AuditID: c1b4fb3a-851ff70000005461-04-5cba3be7b984 Received: from ESESSMB502.ericsson.se (Unknown_Domain [153.88.183.120]) by sessmg22.ericsson.net (Symantec Mail Security) with SMTP id 0F.56.21601.7EB3ABC5; Fri, 19 Apr 2019 23:21:43 +0200 (CEST) Received: from ESESSMB501.ericsson.se (153.88.183.162) by ESESSMB502.ericsson.se (153.88.183.163) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Fri, 19 Apr 2019 23:21:43 +0200 Received: from selio1a020.lmera.ericsson.se (153.88.183.153) by smtp.internal.ericsson.com (153.88.183.189) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Fri, 19 Apr 2019 23:21:43 +0200 Received: from breslau.lmera.ericsson.se (breslau.lmera.ericsson.se [150.132.109.241]) by selio1a020.lmera.ericsson.se (8.15.1+Sun/8.15.1) with ESMTP id x3JLLf29022797; Fri, 19 Apr 2019 23:21:43 +0200 (CEST) From: =?utf-8?q?Mattias_R=C3=B6nnblom?= To: CC: , =?utf-8?q?Mattias_R=C3=B6nnblom?= Date: Fri, 19 Apr 2019 23:21:38 +0200 Message-ID: <20190419212138.17422-3-mattias.ronnblom@ericsson.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190419212138.17422-1-mattias.ronnblom@ericsson.com> References: <20190408123029.6701-1-mattias.ronnblom@ericsson.com> <20190419212138.17422-1-mattias.ronnblom@ericsson.com> MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrLLMWRmVeSWpSXmKPExsUyM2J7he5z610xBivmG1q8+7SdyWLxHTkH Jo9fC5ayevScnMcUwBTFZZOSmpNZllqkb5fAlXFzRgNbwVGRile7lzM1ME4X7GLk5JAQMJE4 1zKLqYuRi0NI4CijxM71LcwQzjdGiZPXf7FAOBcZJeYd6mCDcC4zSiy/+4MVpJ9NwFNi8rtu FhBbREBIYunHy+wgNrNAusTG051MILawgL9E/6VvYPUsAqoSHe9vAcU5OHgFnCS2nauAOENe YvWGA8wgNqeAs8T6g8fAyoUEqiSmrn8ANoZXQFDi5MwnLBDjNSVat/+GWiUv0bx1NjNEvZbE /SVfmCcwCs1C0jILScssJC0LGJlXMYoWpxYX56YbGemlFmUmFxfn5+nlpZZsYgQG8sEtv612 MB587niIUYCDUYmHd6rarhgh1sSy4srcQ4wSHMxKIryOKVtihHhTEiurUovy44tKc1KLDzFK c7AoifP+ERKMERJITyxJzU5NLUgtgskycXBKNTBW/V3u8pcjYZef+naHKbJXKjMXLKu+VLu0 5M29F97tX1JbmSYKNUn/UtmzebacohUT17EVa+tD3utOdN5UK/Iyp+Tt/l2rJV/nn5sryrWn 93VMq0PMCtuPqrFTGhffEjHqnLzdfKXaxcCOKT4hEiKGEd0d+yvb4xZNsbn2Vcwg+nyhp1Jx tboSS3FGoqEWc1FxIgBxRwzWYAIAAA== Subject: [dpdk-dev] [RFC v2 2/2] eal: introduce random generator function with upper bound X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add a function rte_rand_max() which generates an uniformly distributed pseudo-random number less than a user-specified upper bound. The commonly used pattern rte_rand() % SOME_VALUE, in addition to being slow, also creates biased results if SOME_VALUE is not a power of 2. This bias is very small for small SOME_VALUE, but increases linearly with larger SOME_VALUE. Signed-off-by: Mattias Rönnblom --- lib/librte_eal/common/include/rte_random.h | 16 ++++++++++++++++ lib/librte_eal/common/rte_random.c | 20 ++++++++++++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 3 files changed, 37 insertions(+) diff --git a/lib/librte_eal/common/include/rte_random.h b/lib/librte_eal/common/include/rte_random.h index 66dfe8ae7..053912168 100644 --- a/lib/librte_eal/common/include/rte_random.h +++ b/lib/librte_eal/common/include/rte_random.h @@ -47,6 +47,22 @@ rte_srand(uint64_t seedval); uint64_t rte_rand(void); +/** + * Generates a pseudo-random number less than upper_bound. + * + * This function returns an uniformly distributed (unbiased) random + * number lower than a user-specified maximum value. + * + * If called from lcore threads, this function is thread-safe. + * + * @param upper_bound + * The upper bound of the generated number. + * @return + * A pseudo-random value between 0 and (upper_bound-1). + */ +uint64_t +rte_rand_max(uint64_t upper_bound); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/common/rte_random.c b/lib/librte_eal/common/rte_random.c index 288e7b8c5..bf9240470 100644 --- a/lib/librte_eal/common/rte_random.c +++ b/lib/librte_eal/common/rte_random.c @@ -131,6 +131,26 @@ rte_rand(void) return __rte_rand_lfsr258(state); } +uint64_t __rte_experimental +rte_rand_max(uint64_t upper_bound) +{ + uint8_t zeros; + uint64_t mask = ~((uint64_t)0); + uint64_t res; + + if (upper_bound < 2) + return 0; + + zeros = __builtin_clzll(upper_bound); + mask >>= zeros; + + do { + res = rte_rand() & mask; + } while (unlikely(res >= upper_bound)); + + return res; +} + RTE_INIT(rte_rand_init) { rte_srand(rte_get_timer_cycles()); diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 0d60668fa..8f5b8c6a6 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -367,6 +367,7 @@ EXPERIMENTAL { rte_mp_sendmsg; rte_option_register; rte_rand; + rte_rand_max; rte_realloc_socket; rte_service_lcore_attr_get; rte_service_lcore_attr_reset_all;