From patchwork Mon Mar 7 23:00:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ravi Kerur X-Patchwork-Id: 11157 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 [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 231BC374C; Tue, 8 Mar 2016 00:00:49 +0100 (CET) Received: from mail-pf0-f194.google.com (mail-pf0-f194.google.com [209.85.192.194]) by dpdk.org (Postfix) with ESMTP id 5D46D2FDD for ; Tue, 8 Mar 2016 00:00:47 +0100 (CET) Received: by mail-pf0-f194.google.com with SMTP id q129so8884068pfb.3 for ; Mon, 07 Mar 2016 15:00:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BbeFPyHGRb7dtxpIyFwlBWchTJvGg2OgaSY0lFarqus=; b=dWektAUBg8m8vyyvGVYLyJpgNtnA4EbK4nmsvlmjFRhfOF2r5hA/j8Xbl+rquzSX8D PKoIuQf3kdPkVUoci/CY/X642NnAfl+zRAujfK0nGqjjtvp0n7Fyje/Jc52bWrZkWcBQ HO8ArOKxdi5NTPva4RuEd/LRnoJjRdYsKWxnfGYZrJkiRwqVsgx8PXqyYXjC/RMq15zY zyt8xHt70iaRJq7G/pOKDYki+7GEMwgVxzOOYXwIO0lrUG5C8tYQK5D8k5XO6/3hvnwd 52BVtlHUsK6Q1mXI3Eu6iDRN9OAlNpzkopiZTb67gkY9QRKnuqWV2aC0Ictg7x4fsywb 8rZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BbeFPyHGRb7dtxpIyFwlBWchTJvGg2OgaSY0lFarqus=; b=fiUZtYz4cfiR8Ce+MKEL4Yu1zFBjlMBTFzxy1cxHEEYgrnbVsQVE7fbWmo/nz/xYRM Eppu8iVaYN/CUBTByUOIEseuIwPS2fWOi9fKjh/E68mGINhn65ddlnacyAVG3gE1gPqm 64jBJ6pem8JUlYvfbg6fLnaY9Nh6G37E9a48cYmrX6+GzQ2mXWGy9Vf3PZRQ4eYQWyWA da0HQEtli1P6hPP1tvQfHoL1PtqcrC5GQAPwJzc/EPur9JRDPfgUPWKfN0KhEPN7cFF0 DFxsWtsiEdamFygq94Tu3+Q7qm16qr9myZYF9X1aCf6GgD0YaGhrAkl9nSoiiESzFa7B jrIQ== X-Gm-Message-State: AD7BkJL4V2h3sOfcEvV+LT73etjMqqhyG6onEd+XubWMJPrMwICO92lFQzVcpG/lORF1zA== X-Received: by 10.98.0.11 with SMTP id 11mr37419425pfa.5.1457391646731; Mon, 07 Mar 2016 15:00:46 -0800 (PST) Received: from user-PC.hsd1.ca.comcast.net (c-24-130-109-45.hsd1.ca.comcast.net. [24.130.109.45]) by smtp.gmail.com with ESMTPSA id h85sm26323807pfj.52.2016.03.07.15.00.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 Mar 2016 15:00:46 -0800 (PST) From: Ravi Kerur To: dev@dpdk.org Date: Mon, 7 Mar 2016 15:00:44 -0800 Message-Id: <1457391644-29645-2-git-send-email-rkerur@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1457391644-29645-1-git-send-email-rkerur@gmail.com> References: <1457391583-29604-1-git-send-email-rkerur@gmail.com> <1457391644-29645-1-git-send-email-rkerur@gmail.com> Subject: [dpdk-dev] [PATCH v1 2/2] Test cases for rte_memcmp functions 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" v1: This patch adds test cases for rte_memcmp functions. New rte_memcmp functions can be tested via 'make test' and 'testpmd' utility. Compiled and tested on Ubuntu 14.04(non-NUMA) and 15.10(NUMA) systems. Signed-off-by: Ravi Kerur --- app/test/Makefile | 31 +++- app/test/autotest_data.py | 19 +++ app/test/test_memcmp.c | 250 ++++++++++++++++++++++++++++ app/test/test_memcmp_perf.c | 396 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 695 insertions(+), 1 deletion(-) create mode 100644 app/test/test_memcmp.c create mode 100644 app/test/test_memcmp_perf.c diff --git a/app/test/Makefile b/app/test/Makefile index ec33e1a..f6ecaa9 100644 --- a/app/test/Makefile +++ b/app/test/Makefile @@ -82,6 +82,9 @@ SRCS-y += test_logs.c SRCS-y += test_memcpy.c SRCS-y += test_memcpy_perf.c +SRCS-y += test_memcmp.c +SRCS-y += test_memcmp_perf.c + SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash.c SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_thash.c SRCS-$(CONFIG_RTE_LIBRTE_HASH) += test_hash_perf.c @@ -160,14 +163,40 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -D_GNU_SOURCE -# Disable VTA for memcpy test +# Disable VTA for memcpy and memcmp tests ifeq ($(CC), gcc) ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1) CFLAGS_test_memcpy.o += -fno-var-tracking-assignments CFLAGS_test_memcpy_perf.o += -fno-var-tracking-assignments + +CFLAGS_test_memcmp.o += -fno-var-tracking-assignments +CFLAGS_test_memcmp_perf.o += -fno-var-tracking-assignments + endif endif +CMP_AVX2_SUPPORT=$(shell $(CC) -march=core-avx2 -dM -E - &1 | \ + grep -q AVX2 && echo 1) + +ifeq ($(CMP_AVX2_SUPPORT), 1) + ifeq ($(CC), icc) + CFLAGS_test_memcmp.o += -march=core-avx2 + CFLAGS_test_memcmp_perf.o += -march=core-avx2 + else + CFLAGS_test_memcmp.o += -mavx2 + CFLAGS_test_memcmp_perf.o += -mavx2 + endif +else + ifeq ($(CC), icc) + CFLAGS_test_memcmp.o += -march=core-sse4.1 + CFLAGS_test_memcmp_perf.o += -march=core-sse4.1 + else + CFLAGS_test_memcmp.o += -msse4.1 + CFLAGS_test_memcmp_perf.o += -msse4.1 + endif +endif + + # this application needs libraries first DEPDIRS-y += lib drivers diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py index 6f34d6b..5113327 100644 --- a/app/test/autotest_data.py +++ b/app/test/autotest_data.py @@ -186,6 +186,12 @@ parallel_test_group_list = [ "Report" : None, }, { + "Name" : "Memcmp autotest", + "Command" : "memcmp_autotest", + "Func" : default_autotest, + "Report" : None, + }, + { "Name" : "Memzone autotest", "Command" : "memzone_autotest", "Func" : default_autotest, @@ -398,6 +404,19 @@ non_parallel_test_group_list = [ ] }, { + "Prefix": "memcmp_perf", + "Memory" : per_sockets(512), + "Tests" : + [ + { + "Name" : "Memcmp performance autotest", + "Command" : "memcmp_perf_autotest", + "Func" : default_autotest, + "Report" : None, + }, + ] +}, +{ "Prefix": "hash_perf", "Memory" : per_sockets(512), "Tests" : diff --git a/app/test/test_memcmp.c b/app/test/test_memcmp.c new file mode 100644 index 0000000..e3b0bf7 --- /dev/null +++ b/app/test/test_memcmp.c @@ -0,0 +1,250 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/******************************************************************************* + * Memcmp function performance test configuration section. + * Each performance test will be performed HASHTEST_ITERATIONS times. + * + * The five arrays below control what tests are performed. Every combination + * from the array entries is tested. + */ +static size_t memcmp_sizes[] = { + 1, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255, + 256, 257, 320, 384, 511, 512, 513, 1023, 1024, 1025, 1518, 1522, 1600, + 2048, 3072, 4096, 5120, 6144, 7168, 8192, 16384 +}; + +/******************************************************************************/ + +#define RTE_MEMCMP_LENGTH_MAX 16384 + +/* + * Test a memcmp equal function. + */ +static int run_memcmp_eq_func_test(uint32_t len) +{ + uint32_t i, rc; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) { + printf("\nkey_1 is null\n"); + return -1; + } + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + rte_free(key_1); + printf("\nkey_2 is null\n"); + return -1; + } + + for (i = 0; i < len; i++) + key_1[i] = 1; + + for (i = 0; i < len; i++) + key_2[i] = 1; + + rc = rte_memcmp(key_1, key_2, len); + rte_free(key_1); + rte_free(key_2); + + return rc; +} + +/* + * Test memcmp equal functions. + */ +static int run_memcmp_eq_func_tests(void) +{ + unsigned i; + + for (i = 0; + i < sizeof(memcmp_sizes) / sizeof(memcmp_sizes[0]); + i++) { + if (run_memcmp_eq_func_test(memcmp_sizes[i])) { + printf("Comparing equal %zd bytes failed\n", memcmp_sizes[i]); + return 1; + } + } + printf("RTE memcmp for equality successful\n"); + return 0; +} + +/* + * Test a memcmp less than function. + */ +static int run_memcmp_lt_func_test(uint32_t len) +{ + uint32_t i, rc; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) + return -1; + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + rte_free(key_1); + return -1; + } + + for (i = 0; i < len; i++) + key_1[i] = 1; + + for (i = 0; i < len; i++) + key_2[i] = 2; + + rc = rte_memcmp(key_1, key_2, len); + rte_free(key_1); + rte_free(key_2); + + return rc; +} + +/* + * Test memcmp less than functions. + */ +static int run_memcmp_lt_func_tests(void) +{ + unsigned i; + + for (i = 0; + i < sizeof(memcmp_sizes) / sizeof(memcmp_sizes[0]); + i++) { + if (!(run_memcmp_lt_func_test(memcmp_sizes[i]) < 0)) { + printf("Comparing less than for %zd bytes failed\n", memcmp_sizes[i]); + return 1; + } + } + printf("RTE memcmp for less than successful\n"); + return 0; +} + +/* + * Test a memcmp greater than function. + */ +static int run_memcmp_gt_func_test(uint32_t len) +{ + uint32_t i, rc; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) + return -1; + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + rte_free(key_1); + return -1; + } + + for (i = 0; i < len; i++) + key_1[i] = 2; + + for (i = 0; i < len; i++) + key_2[i] = 1; + + rc = rte_memcmp(key_1, key_2, len); + rte_free(key_1); + rte_free(key_2); + + return rc; +} + +/* + * Test memcmp less than functions. + */ +static int run_memcmp_gt_func_tests(void) +{ + unsigned i; + + for (i = 0; + i < sizeof(memcmp_sizes) / sizeof(memcmp_sizes[0]); + i++) { + if (!(run_memcmp_gt_func_test(memcmp_sizes[i]) > 0)) { + printf("Comparing greater than for %zd bytes failed\n", memcmp_sizes[i]); + return 1; + } + } + printf("RTE memcmp for greater than successful\n"); + return 0; +} + +/* + * Do all unit and performance tests. + */ +static int +test_memcmp(void) +{ + if (run_memcmp_eq_func_tests()) + return -1; + + if (run_memcmp_gt_func_tests()) + return -1; + + if (run_memcmp_lt_func_tests()) + return -1; + + return 0; +} + +static struct test_command memcmp_cmd = { + .command = "memcmp_autotest", + .callback = test_memcmp, +}; +REGISTER_TEST_COMMAND(memcmp_cmd); diff --git a/app/test/test_memcmp_perf.c b/app/test/test_memcmp_perf.c new file mode 100644 index 0000000..4c0f4d9 --- /dev/null +++ b/app/test/test_memcmp_perf.c @@ -0,0 +1,396 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/******************************************************************************* + * Memcmp function performance test configuration section. Each performance test + * will be performed MEMCMP_ITERATIONS times. + * + * The five arrays below control what tests are performed. Every combination + * from the array entries is tested. + */ +#define MEMCMP_ITERATIONS (500 * 500 * 500) + +static size_t memcmp_sizes[] = { + 2, 5, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, + 129, 191, 192, 193, 255, 256, 257, 319, 320, 321, 383, 384, + 385, 447, 448, 449, 511, 512, 513, 767, 768, 769, 1023, 1024, + 1025, 1522, 1536, 1600, 2048, 2560, 3072, 3584, 4096, 4608, + 5632, 6144, 6656, 7168, 7680, 8192, 16834 +}; + +static size_t memcmp_lt_gt_sizes[] = { + 1, 8, 15, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 +}; + +/******************************************************************************/ + +static int +run_single_memcmp_eq_perf_test(uint32_t len, int func_type, uint64_t iterations) +{ + uint32_t i, j; + + double begin = 0, end = 0; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + int rc = 0; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) { + printf("\nkey_1 mem alloc failure\n"); + return -1; + } + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + printf("\nkey_2 mem alloc failure\n"); + rte_free(key_2); + return -1; + } + + /* Prepare inputs for the current iteration */ + for (j = 0; j < len; j++) + key_1[j] = key_2[j] = j / 64; + + begin = rte_rdtsc(); + + /* Perform operation, and measure time it takes */ + for (i = 0; i < iterations; i++) { + + switch (func_type) { + case 1: + rc += rte_memcmp(key_1, key_2, len); + break; + case 2: + rc += memcmp(key_1, key_2, len); + break; + default: + break; + } + + } + + end = rte_rdtsc() - begin; + + printf(" *** %10i, %10.4f ***\n", len, (double)(end/iterations)); + + rte_free(key_1); + rte_free(key_2); + + return rc; +} + +/* + * Run all memcmp table performance tests. + */ +static int run_all_memcmp_eq_perf_tests(void) +{ + unsigned i; + + printf(" *** RTE memcmp equal performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_sizes) / sizeof(memcmp_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_eq_perf_test(memcmp_sizes[i], 1, + MEMCMP_ITERATIONS) != 0) + return -1; + } + + printf(" *** memcmp equal performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_sizes) / sizeof(memcmp_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_eq_perf_test(memcmp_sizes[i], 2, + MEMCMP_ITERATIONS) != 0) + return -1; + } + return 0; +} + +static int +run_single_memcmp_lt_perf_test(uint32_t len, int func_type, + uint64_t iterations) +{ + uint32_t i, j; + + double begin = 0, end = 0; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + int rc; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) { + printf("\nKey_1 lt mem alloc failure\n"); + return -1; + } + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + printf("\nKey_2 lt mem alloc failure\n"); + rte_free(key_1); + return -1; + } + + /* Prepare inputs for the current iteration */ + for (j = 0; j < len; j++) + key_1[j] = 1; + + for (j = 0; j < len; j++) + key_2[j] = 1; + + /* Perform operation, and measure time it takes */ + for (i = 0; i < iterations; i++) { + + key_2[i % len] = 2; + + switch (func_type) { + case 1: + begin = rte_rdtsc(); + rc = rte_memcmp(key_1, key_2, len); + end += rte_rdtsc() - begin; + break; + case 2: + begin = rte_rdtsc(); + rc = memcmp(key_1, key_2, len); + end += rte_rdtsc() - begin; + break; + default: + break; + } + + key_2[i % len] = 1; + + if (!(rc < 0)) { + printf("\nrc %d i %d\n", rc, i); + return -1; + } + } + + printf(" *** %10i, %10.4f ***\n", len, (double)(end/iterations)); + + rte_free(key_1); + rte_free(key_2); + + return 0; +} + +/* + * Run all memcmp table performance tests. + */ +static int run_all_memcmp_lt_perf_tests(void) +{ + unsigned i; + + printf(" *** RTE memcmp less than performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_lt_gt_sizes) / sizeof(memcmp_lt_gt_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_lt_perf_test(memcmp_lt_gt_sizes[i], 1, + MEMCMP_ITERATIONS) != 0) + return -1; + } + + printf(" *** memcmp less than performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_lt_gt_sizes) / sizeof(memcmp_lt_gt_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_lt_perf_test(memcmp_lt_gt_sizes[i], 2, + MEMCMP_ITERATIONS) != 0) + return -1; + } + return 0; +} + +static int +run_single_memcmp_gt_perf_test(uint32_t len, int func_type, + uint64_t iterations) +{ + uint32_t i, j; + + double begin = 0, end = 0; + + uint8_t *volatile key_1 = NULL; + uint8_t *volatile key_2 = NULL; + int rc; + + key_1 = rte_zmalloc("memcmp key_1", len * sizeof(uint8_t), 16); + if (key_1 == NULL) { + printf("\nkey_1 gt mem alloc failure\n"); + return -1; + } + + key_2 = rte_zmalloc("memcmp key_2", len * sizeof(uint8_t), 16); + if (key_2 == NULL) { + printf("\nkey_2 gt mem alloc failure\n"); + rte_free(key_1); + return -1; + } + + /* Prepare inputs for the current iteration */ + for (j = 0; j < len; j++) + key_1[j] = 1; + + for (j = 0; j < len; j++) + key_2[j] = 1; + + /* Perform operation, and measure time it takes */ + for (i = 0; i < iterations; i++) { + key_1[i % len] = 2; + + switch (func_type) { + case 1: + begin = rte_rdtsc(); + rc = rte_memcmp(key_1, key_2, len); + end += rte_rdtsc() - begin; + break; + case 2: + begin = rte_rdtsc(); + rc = memcmp(key_1, key_2, len); + end += rte_rdtsc() - begin; + break; + default: + break; + } + + key_1[i % len] = 1; + + if (!(rc > 0)) { + printf("\nrc %d i %d\n", rc, i); + for (i = 0; i < len; i++) + printf("\nkey_1 %d key_2 %d mod %d\n", key_1[i], key_2[i], (i % len)); + return -1; + } + } + + printf(" *** %10i, %10.4f ***\n", len, (double)(end/iterations)); + + rte_free(key_1); + rte_free(key_2); + + return 0; +} + +/* + * Run all memcmp table performance tests. + */ +static int run_all_memcmp_gt_perf_tests(void) +{ + unsigned i; + + printf(" *** RTE memcmp greater than performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_lt_gt_sizes) / sizeof(memcmp_lt_gt_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_gt_perf_test(memcmp_lt_gt_sizes[i], 1, + MEMCMP_ITERATIONS) != 0) + return -1; + } + + printf(" *** memcmp greater than performance test results ***\n"); + printf(" *** Length (bytes), Ticks/Op. ***\n"); + + /* Loop through every combination of test parameters */ + for (i = 0; + i < sizeof(memcmp_lt_gt_sizes) / sizeof(memcmp_lt_gt_sizes[0]); + i++) { + /* Perform test */ + if (run_single_memcmp_gt_perf_test(memcmp_lt_gt_sizes[i], 2, + MEMCMP_ITERATIONS) != 0) + return -1; + } + return 0; +} + +/* + * Do all performance tests. + */ +static int +test_memcmp_perf(void) +{ + if (run_all_memcmp_eq_perf_tests() != 0) + return -1; + + if (run_all_memcmp_gt_perf_tests() != 0) + return -1; + + if (run_all_memcmp_lt_perf_tests() != 0) + return -1; + + + return 0; +} + +static struct test_command memcmp_perf_cmd = { + .command = "memcmp_perf_autotest", + .callback = test_memcmp_perf, +}; +REGISTER_TEST_COMMAND(memcmp_perf_cmd);