From patchwork Wed Jan 19 21:09:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Kozlyuk X-Patchwork-Id: 106097 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DAE53A0351; Wed, 19 Jan 2022 22:09:44 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0DB0E411DD; Wed, 19 Jan 2022 22:09:42 +0100 (CET) Received: from NAM04-MW2-obe.outbound.protection.outlook.com (mail-mw2nam08on2082.outbound.protection.outlook.com [40.107.101.82]) by mails.dpdk.org (Postfix) with ESMTP id F0F93411C3 for ; Wed, 19 Jan 2022 22:09:39 +0100 (CET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TvEUHA4dX2/eaPltkEcEZlyslCNE3axMYKM0vB0c++N1t3lxRA5h7v2YGnkse65ZW0yp6p8Vx6FV4TvNoVx7r4klk2JQsVCqQzGxVAxV70XwqwyJI0z9dlGGbpgqnUd+SYKnC+Y83xQHIqa7Nodf+Un2Fw4tqWtPmKw4rz0YCpvKv+bMfMLzRjeufzDvoialroK7UJ56v4ENAoEMG25yydsB1uEiyIKRd5SDUjR/XvG05jQRfgdXFH8nWb5nsnaFq+fDDKTk63odvXxUddBrR9ohiEOjgXajuEaUCRcIK0+bf/q83nZbIw9Q+u2XYDX5G7auV0MoY+gYPAVvPaJhYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yk4dkLSKW1fqthvfZfACIKWGgaotdk8ede0xk2qkPv8=; b=jkTNfeAm60euF2URBlkjib9UCaSZEkDiAp7tihHc0obz2QZLauLaMuSlWclOSXl2tdBeGXCmAiXlT2RMp0p8JkpIQ6fjP1aj/2uxh695XDdaSkhm9EwaZcNh7IacCPcKr6iKs22zoZXuVnnxHUt1Y4+4DdRHgzgsb5r1oSbYR31BRn16akvFmn1ykQhmOoF+OMZUFwal1LY4oUZnn95XDNCiqLcD/8PyoVY5J6TabZlqU67Exc51PlxX6XDvP1Lht7IcWT1txgGMfJgQobcOAsl4II8YRp3koJzG5R9A5tuKOkTWwsUfCHvlJF638fA+j5+YVm4vdj03QGRhI1i5CA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 12.22.5.234) smtp.rcpttodomain=redhat.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=yk4dkLSKW1fqthvfZfACIKWGgaotdk8ede0xk2qkPv8=; b=SbUWu75gKeJcREMHeCEluijrzFb2LvykKsaISOtmrQLKkvp0jCuW0lNePbtzurCIMoNhmuLxuO6dfOTBhc9PhWYV3s+jImi6GfhqL1yYkQbJ+w4c5670yq8P/AYg389qqvKgzQ6dNzFWR2F+vAoaAlR9euHqUmvWrYQY02Osg7lQmYe+Feb1keZtl9qHIQdoc6k6FBEA81WM6Di6/FT/Q+IjMwItJrLcVe67NriQuYE2EdpiVQQOOfnCcEANwlQv9MvwWj3vrK2ZYv3iFoS7MlFjjl2xjCxuE8nxPS60QE+rdgYA/PuWZn4GiuVEH0eLYVJf3VqsHhjmE/WRZ7L75w== Received: from MW2PR16CA0023.namprd16.prod.outlook.com (2603:10b6:907::36) by PH0PR12MB5483.namprd12.prod.outlook.com (2603:10b6:510:ee::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4888.11; Wed, 19 Jan 2022 21:09:38 +0000 Received: from CO1NAM11FT065.eop-nam11.prod.protection.outlook.com (2603:10b6:907:0:cafe::38) by MW2PR16CA0023.outlook.office365.com (2603:10b6:907::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4909.8 via Frontend Transport; Wed, 19 Jan 2022 21:09:37 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 12.22.5.234) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 12.22.5.234 as permitted sender) receiver=protection.outlook.com; client-ip=12.22.5.234; helo=mail.nvidia.com; Received: from mail.nvidia.com (12.22.5.234) by CO1NAM11FT065.mail.protection.outlook.com (10.13.174.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4909.7 via Frontend Transport; Wed, 19 Jan 2022 21:09:37 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by DRHQMAIL101.nvidia.com (10.27.9.10) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 19 Jan 2022 21:09:36 +0000 Received: from nvidia.com (10.126.230.35) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.986.9; Wed, 19 Jan 2022 13:09:35 -0800 From: Dmitry Kozlyuk To: CC: Bruce Richardson , Viacheslav Ovsiienko , Aaron Conole Subject: [PATCH v2 2/6] app/test: add allocator performance benchmark Date: Wed, 19 Jan 2022 23:09:13 +0200 Message-ID: <20220119210917.765505-3-dkozlyuk@nvidia.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220119210917.765505-1-dkozlyuk@nvidia.com> References: <20220117080801.481568-1-dkozlyuk@nvidia.com> <20220119210917.765505-1-dkozlyuk@nvidia.com> MIME-Version: 1.0 X-Originating-IP: [10.126.230.35] X-ClientProxiedBy: HQMAIL105.nvidia.com (172.20.187.12) To rnnvmail201.nvidia.com (10.129.68.8) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2fdbe070-9511-41a3-ba39-08d9db900067 X-MS-TrafficTypeDiagnostic: PH0PR12MB5483:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:3968; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: YW0vePU61X8iNisgiolU+vHMpwdbqI347je5ylGqN3TwjBfSVoj/RPfiNoHCOB/1o1zsRSa+LhU19f5Xy6VA+2MrJVq+6RccMpZDB9G8/XFTzUy/Ri76mH0gMSSRsrb9Ak1wEMf/diDnJqcUrqxbnAKk5ToMfgntFj+HCGKW9zTrINlmfvmveszUKVGpJhYbY2RD3QRinJ/wwkpZsTMn3aeVb9F52fxUaWZO4frVF1+MH9Y/rmnIjAmDyLJXeN6KTctrPJGB20/4r7bRCyfSMBwKUC07133Ry8nb9aD6HIFdEDFa2JDRXJMezIz7q2LQtAVCoPG5YnpZ/HI918vh7s+IVw6F2buTIdapqt31lVeDfrsHILUfBlfKT+SlJ8Drfq0+gw3fpvTwhuODuNX5yVHdzapGyGbHpx8SIH1mODtozG8AoVIANbIgeQrfLS4766CUThuGndt7sSpKjLgm+6uObqKzI8fwlVpC7MTN+7TwuzjHdZgvaRox38NLhhL5QbCkAnvyLAhZxUlRmciRqfFHNX7knJCc/Kt76dY+mKi0j+C6Le0HxlCNYNk+qIpgec7bLYDCt9rfZYaXnKlNn6xvqrVU3gKHyIjIuedmhMAKzTPSN078zK9WKdx87CCMw2knDAGgIOb2bMfklWrDcvEUyuAryYRFy9wrMlps0YMO1UZ/BOFl7f+2Q9WDtPhOpZWd7zM4LsUdAtRGxPtkl+ZpLB8eY3zpZ2tDFpa7eOyeV4Q+N2aP3VlG4uI69MMm6wtSTuNl3b0sP9d/Cmgp/IQfIbm6k4mUJPhYDLmERHI= X-Forefront-Antispam-Report: CIP:12.22.5.234; CTRY:US; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:mail.nvidia.com; PTR:InfoNoRecords; CAT:NONE; SFS:(4636009)(46966006)(36840700001)(40470700002)(2616005)(36860700001)(40460700001)(54906003)(426003)(8676002)(16526019)(36756003)(70586007)(26005)(6916009)(186003)(70206006)(2906002)(356005)(4326008)(5660300002)(47076005)(55016003)(8936002)(7696005)(336012)(82310400004)(86362001)(508600001)(6286002)(6666004)(81166007)(316002)(1076003)(36900700001); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Jan 2022 21:09:37.5551 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2fdbe070-9511-41a3-ba39-08d9db900067 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[12.22.5.234]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT065.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB5483 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Memory allocator performance is crucial to applications that deal with large amount of memory or allocate frequently. DPDK allocator performance is affected by EAL options, API used and, at least, allocation size. New autotest is intended to be run with different EAL options. It measures performance with a range of sizes for dirrerent APIs: rte_malloc, rte_zmalloc, and rte_memzone_reserve. Work distribution between allocation and deallocation depends on EAL options. The test prints both times and total time to ease comparison. Memory can be filled with zeroes at different points of allocation path, but it always takes considerable fraction of overall timing. This is why the test measures filling speed and prints how long clearing takes for each size as a reference (for rte_memzone_reserve estimations are printed). Signed-off-by: Dmitry Kozlyuk Reviewed-by: Viacheslav Ovsiienko Acked-by: Aaron Conole --- app/test/meson.build | 2 + app/test/test_malloc_perf.c | 174 ++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 app/test/test_malloc_perf.c diff --git a/app/test/meson.build b/app/test/meson.build index 344a609a4d..50cf2602a9 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -88,6 +88,7 @@ test_sources = files( 'test_lpm6_perf.c', 'test_lpm_perf.c', 'test_malloc.c', + 'test_malloc_perf.c', 'test_mbuf.c', 'test_member.c', 'test_member_perf.c', @@ -295,6 +296,7 @@ extra_test_names = [ perf_test_names = [ 'ring_perf_autotest', + 'malloc_perf_autotest', 'mempool_perf_autotest', 'memcpy_perf_autotest', 'hash_perf_autotest', diff --git a/app/test/test_malloc_perf.c b/app/test/test_malloc_perf.c new file mode 100644 index 0000000000..9686fc8af5 --- /dev/null +++ b/app/test/test_malloc_perf.c @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2021 NVIDIA Corporation & Affiliates + */ + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +#define TEST_LOG(level, ...) RTE_LOG(level, USER1, __VA_ARGS__) + +typedef void * (alloc_t)(const char *name, size_t size, unsigned int align); +typedef void (free_t)(void *addr); +typedef void * (memset_t)(void *addr, int value, size_t size); + +static const uint64_t KB = 1 << 10; +static const uint64_t GB = 1 << 30; + +static double +tsc_to_us(uint64_t tsc, size_t runs) +{ + return (double)tsc / rte_get_tsc_hz() * US_PER_S / runs; +} + +static int +test_memset_perf(double *us_per_gb) +{ + static const size_t RUNS = 20; + + void *ptr; + size_t i; + uint64_t tsc; + + TEST_LOG(INFO, "Reference: memset\n"); + + ptr = rte_malloc(NULL, GB, 0); + if (ptr == NULL) { + TEST_LOG(ERR, "rte_malloc(size=%"PRIx64") failed\n", GB); + return -1; + } + + tsc = rte_rdtsc_precise(); + for (i = 0; i < RUNS; i++) + memset(ptr, 0, GB); + tsc = rte_rdtsc_precise() - tsc; + + *us_per_gb = tsc_to_us(tsc, RUNS); + TEST_LOG(INFO, "Result: %f.3 GiB/s <=> %.2f us/MiB\n", + US_PER_S / *us_per_gb, *us_per_gb / KB); + + rte_free(ptr); + TEST_LOG(INFO, "\n"); + return 0; +} + +static int +test_alloc_perf(const char *name, alloc_t *alloc_fn, free_t *free_fn, + memset_t *memset_fn, double memset_gb_us, size_t max_runs) +{ + static const size_t SIZES[] = { + 1 << 6, 1 << 7, 1 << 10, 1 << 12, 1 << 16, 1 << 20, + 1 << 21, 1 << 22, 1 << 24, 1 << 30 }; + + size_t i, j; + void **ptrs; + + TEST_LOG(INFO, "Performance: %s\n", name); + + ptrs = calloc(max_runs, sizeof(ptrs[0])); + if (ptrs == NULL) { + TEST_LOG(ERR, "Cannot allocate memory for pointers"); + return -1; + } + + TEST_LOG(INFO, "%12s%8s%12s%12s%12s%17s\n", "Size (B)", "Runs", + "Alloc (us)", "Free (us)", "Total (us)", + memset_fn != NULL ? "memset (us)" : "est.memset (us)"); + for (i = 0; i < RTE_DIM(SIZES); i++) { + size_t size = SIZES[i]; + size_t runs_done; + uint64_t tsc_start, tsc_alloc, tsc_memset = 0, tsc_free; + double alloc_time, free_time, memset_time; + + tsc_start = rte_rdtsc_precise(); + for (j = 0; j < max_runs; j++) { + ptrs[j] = alloc_fn(NULL, size, 0); + if (ptrs[j] == NULL) + break; + } + tsc_alloc = rte_rdtsc_precise() - tsc_start; + + if (j == 0) { + TEST_LOG(INFO, "%12zu Interrupted: out of memory.\n", + size); + break; + } + runs_done = j; + + if (memset_fn != NULL) { + tsc_start = rte_rdtsc_precise(); + for (j = 0; j < runs_done && ptrs[j] != NULL; j++) + memset_fn(ptrs[j], 0, size); + tsc_memset = rte_rdtsc_precise() - tsc_start; + } + + tsc_start = rte_rdtsc_precise(); + for (j = 0; j < runs_done && ptrs[j] != NULL; j++) + free_fn(ptrs[j]); + tsc_free = rte_rdtsc_precise() - tsc_start; + + alloc_time = tsc_to_us(tsc_alloc, runs_done); + free_time = tsc_to_us(tsc_free, runs_done); + memset_time = memset_fn != NULL ? + tsc_to_us(tsc_memset, runs_done) : + memset_gb_us * size / GB; + TEST_LOG(INFO, "%12zu%8zu%12.2f%12.2f%12.2f%17.2f\n", + size, runs_done, alloc_time, free_time, + alloc_time + free_time, memset_time); + + memset(ptrs, 0, max_runs * sizeof(ptrs[0])); + } + + free(ptrs); + TEST_LOG(INFO, "\n"); + return 0; +} + +static void * +memzone_alloc(const char *name __rte_unused, size_t size, unsigned int align) +{ + const struct rte_memzone *mz; + char gen_name[RTE_MEMZONE_NAMESIZE]; + + snprintf(gen_name, sizeof(gen_name), "test-mz-%"PRIx64, rte_rdtsc()); + mz = rte_memzone_reserve_aligned(gen_name, size, SOCKET_ID_ANY, + RTE_MEMZONE_1GB | RTE_MEMZONE_SIZE_HINT_ONLY, align); + return (void *)(uintptr_t)mz; +} + +static void +memzone_free(void *addr) +{ + rte_memzone_free((struct rte_memzone *)addr); +} + +static int +test_malloc_perf(void) +{ + static const size_t MAX_RUNS = 10000; + + double memset_us_gb; + + if (test_memset_perf(&memset_us_gb) < 0) + return -1; + + if (test_alloc_perf("rte_malloc", rte_malloc, rte_free, memset, + memset_us_gb, MAX_RUNS) < 0) + return -1; + if (test_alloc_perf("rte_zmalloc", rte_zmalloc, rte_free, memset, + memset_us_gb, MAX_RUNS) < 0) + return -1; + + if (test_alloc_perf("rte_memzone_reserve", memzone_alloc, memzone_free, + NULL, memset_us_gb, RTE_MAX_MEMZONE - 1) < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(malloc_perf_autotest, test_malloc_perf);