test/thread: Add poller_perf to evaluate cost to run poller
Add a simple tool, poller_perf, to evaluate cost to run non-timed poller or timed poller by any period, number of pollers. struct spdk_thread and struct spdk_thread_stats can have the count of poller runs but we do not have any particular use case for it. So the poller_perf tool use its global counter for now. By following similar tools, event_perf and reactor_perf, run poller_perf once for non-timed poller and once for timed poller. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: Ic5b297bb23d0cd0dc1313e1638ac540ffd5fb8f8 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8925 Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
226a705d83
commit
801bce0d33
@ -177,6 +177,7 @@ if [ $SPDK_RUN_FUNCTIONAL_TEST -eq 1 ]; then
|
|||||||
run_test "spdkcli_tcp" test/spdkcli/tcp.sh
|
run_test "spdkcli_tcp" test/spdkcli/tcp.sh
|
||||||
run_test "dpdk_mem_utility" test/dpdk_memory_utility/test_dpdk_mem_info.sh
|
run_test "dpdk_mem_utility" test/dpdk_memory_utility/test_dpdk_mem_info.sh
|
||||||
run_test "event" test/event/event.sh
|
run_test "event" test/event/event.sh
|
||||||
|
run_test "thread" test/thread/thread.sh
|
||||||
run_test "accel_engine" test/accel_engine/accel_engine.sh
|
run_test "accel_engine" test/accel_engine/accel_engine.sh
|
||||||
|
|
||||||
if [ $SPDK_TEST_BLOCKDEV -eq 1 ]; then
|
if [ $SPDK_TEST_BLOCKDEV -eq 1 ]; then
|
||||||
|
@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/..)
|
|||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
# These directories contain tests.
|
# These directories contain tests.
|
||||||
TESTDIRS = app bdev blobfs cpp_headers env event nvme rpc_client
|
TESTDIRS = app bdev blobfs cpp_headers env event nvme rpc_client thread
|
||||||
|
|
||||||
DIRS-$(CONFIG_TESTS) += $(TESTDIRS)
|
DIRS-$(CONFIG_TESTS) += $(TESTDIRS)
|
||||||
DIRS-$(CONFIG_UNIT_TESTS) += unit
|
DIRS-$(CONFIG_UNIT_TESTS) += unit
|
||||||
|
44
test/thread/Makefile
Normal file
44
test/thread/Makefile
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# BSD LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) Intel Corporation.
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||||
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
|
DIRS-y = poller_perf
|
||||||
|
|
||||||
|
.PHONY: all clean $(DIRS-y)
|
||||||
|
|
||||||
|
all: $(DIRS-y)
|
||||||
|
clean: $(DIRS-y)
|
||||||
|
|
||||||
|
include $(SPDK_ROOT_DIR)/mk/spdk.subdirs.mk
|
1
test/thread/poller_perf/.gitignore
vendored
Normal file
1
test/thread/poller_perf/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
poller_perf
|
42
test/thread/poller_perf/Makefile
Normal file
42
test/thread/poller_perf/Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#
|
||||||
|
# BSD LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) Intel Corporation.
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../../..)
|
||||||
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
|
APP = poller_perf
|
||||||
|
C_SRCS := poller_perf.c
|
||||||
|
|
||||||
|
SPDK_LIB_LIST = event thread
|
||||||
|
|
||||||
|
include $(SPDK_ROOT_DIR)/mk/spdk.app.mk
|
212
test/thread/poller_perf/poller_perf.c
Normal file
212
test/thread/poller_perf/poller_perf.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*-
|
||||||
|
* BSD LICENSE
|
||||||
|
*
|
||||||
|
* Copyright (c) Intel Corporation.
|
||||||
|
* 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 "spdk/stdinc.h"
|
||||||
|
|
||||||
|
#include "spdk/env.h"
|
||||||
|
#include "spdk/event.h"
|
||||||
|
#include "spdk/string.h"
|
||||||
|
#include "spdk/thread.h"
|
||||||
|
#include "spdk/util.h"
|
||||||
|
|
||||||
|
#define MAX_NUM_POLLERS 1000
|
||||||
|
|
||||||
|
static int g_time_in_sec;
|
||||||
|
static int g_period_in_usec;
|
||||||
|
static int g_num_pollers;
|
||||||
|
|
||||||
|
static struct spdk_poller *g_timer;
|
||||||
|
static struct spdk_poller *g_pollers[MAX_NUM_POLLERS];
|
||||||
|
static uint64_t g_run_count;
|
||||||
|
|
||||||
|
static struct spdk_thread_stats g_start_stats;
|
||||||
|
|
||||||
|
static int
|
||||||
|
poller_run(void *arg)
|
||||||
|
{
|
||||||
|
g_run_count++;
|
||||||
|
|
||||||
|
return SPDK_POLLER_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_poller_perf_end(void)
|
||||||
|
{
|
||||||
|
struct spdk_thread_stats end_stats;
|
||||||
|
uint64_t tsc_hz, busy_cyc, poller_cost_cyc, poller_cost_nsec;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
spdk_thread_get_stats(&end_stats);
|
||||||
|
busy_cyc = end_stats.busy_tsc - g_start_stats.busy_tsc;
|
||||||
|
|
||||||
|
tsc_hz = spdk_get_ticks_hz();
|
||||||
|
|
||||||
|
printf("\r ======================================\n");
|
||||||
|
|
||||||
|
printf("\r busy:%" PRIu64 " (cyc)\n", busy_cyc);
|
||||||
|
printf("\r total_run_count: %" PRIu64 "\n", g_run_count);
|
||||||
|
printf("\r tsc_hz: %" PRIu64 " (cyc)\n", tsc_hz);
|
||||||
|
|
||||||
|
printf("\r ======================================\n");
|
||||||
|
|
||||||
|
poller_cost_cyc = busy_cyc / g_run_count;
|
||||||
|
poller_cost_nsec = (poller_cost_cyc * SPDK_SEC_TO_NSEC) / tsc_hz;
|
||||||
|
|
||||||
|
printf("\r poller_cost: %" PRIu64 " (cyc), %" PRIu64 " (nsec)\n",
|
||||||
|
poller_cost_cyc, poller_cost_nsec);
|
||||||
|
|
||||||
|
spdk_poller_unregister(&g_timer);
|
||||||
|
|
||||||
|
for (i = 0; i < g_num_pollers; i++) {
|
||||||
|
spdk_poller_unregister(&g_pollers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_app_stop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
poller_perf_end(void *arg)
|
||||||
|
{
|
||||||
|
_poller_perf_end();
|
||||||
|
|
||||||
|
return SPDK_POLLER_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poller_perf_start(void *arg1)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("Running %d pollers for %d seconds with %d microseconds period.\n",
|
||||||
|
g_num_pollers, g_time_in_sec, g_period_in_usec);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
for (i = 0; i < g_num_pollers; i++) {
|
||||||
|
g_pollers[i] = SPDK_POLLER_REGISTER(poller_run, NULL, g_period_in_usec);
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_thread_get_stats(&g_start_stats);
|
||||||
|
|
||||||
|
g_timer = SPDK_POLLER_REGISTER(poller_perf_end, NULL, g_time_in_sec * SPDK_SEC_TO_USEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poller_perf_shutdown_cb(void)
|
||||||
|
{
|
||||||
|
_poller_perf_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
poller_perf_parse_arg(int ch, char *arg)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
tmp = spdk_strtol(optarg, 10);
|
||||||
|
if (tmp < 0) {
|
||||||
|
fprintf(stderr, "Parse failed for the option %c.\n", ch);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case 'b':
|
||||||
|
g_num_pollers = tmp;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
g_period_in_usec = tmp;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
g_time_in_sec = tmp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
poller_perf_usage(void)
|
||||||
|
{
|
||||||
|
printf(" -b <number> number of pollers\n");
|
||||||
|
printf(" -l <period> poller period in usec\n");
|
||||||
|
printf(" -t <time> run time in seconds\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
poller_perf_verify_params(void)
|
||||||
|
{
|
||||||
|
if (g_num_pollers <= 0 || g_num_pollers > MAX_NUM_POLLERS) {
|
||||||
|
fprintf(stderr, "number of pollers must not be more than %d\n", MAX_NUM_POLLERS);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_period_in_usec < 0) {
|
||||||
|
fprintf(stderr, "period of poller cannot be negative\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_time_in_sec <= 0) {
|
||||||
|
fprintf(stderr, "run time must be positive\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct spdk_app_opts opts;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
spdk_app_opts_init(&opts, sizeof(opts));
|
||||||
|
opts.name = "poller_perf";
|
||||||
|
opts.shutdown_cb = poller_perf_shutdown_cb;
|
||||||
|
|
||||||
|
rc = spdk_app_parse_args(argc, argv, &opts, "b:l:t:", NULL,
|
||||||
|
poller_perf_parse_arg, poller_perf_usage);
|
||||||
|
if (rc != SPDK_APP_PARSE_ARGS_SUCCESS) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = poller_perf_verify_params();
|
||||||
|
if (rc != 0) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = spdk_app_start(&opts, poller_perf_start, NULL);
|
||||||
|
|
||||||
|
spdk_app_fini();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
8
test/thread/thread.sh
Executable file
8
test/thread/thread.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
testdir=$(readlink -f $(dirname $0))
|
||||||
|
rootdir=$(readlink -f $testdir/../..)
|
||||||
|
source $rootdir/test/common/autotest_common.sh
|
||||||
|
|
||||||
|
run_test "thread_poller_perf" $testdir/poller_perf/poller_perf -b 1000 -l 1 -t 1
|
||||||
|
run_test "thread_poller_perf" $testdir/poller_perf/poller_perf -b 1000 -l 0 -t 1
|
Loading…
Reference in New Issue
Block a user