From patchwork Tue Nov 24 23:21:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 11929957 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85DCCC2D0E4 for ; Tue, 24 Nov 2020 23:21:41 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 04D4120BED for ; Tue, 24 Nov 2020 23:21:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 04D4120BED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=chris-wilson.co.uk Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6B9DF6E456; Tue, 24 Nov 2020 23:21:40 +0000 (UTC) Received: from fireflyinternet.com (unknown [77.68.26.236]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7B9126E459 for ; Tue, 24 Nov 2020 23:21:37 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 23097549-1500050 for multiple; Tue, 24 Nov 2020 23:21:23 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 24 Nov 2020 23:21:21 +0000 Message-Id: <20201124232122.445431-1-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 1/2] tools/intel_gpu_top: Include total package power X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedestop.org, Chris Wilson Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" With integrated graphics the TDP is shared between the gpu and the cpu, knowing the total energy consumed by the package is relevant to understanding throttling. v2: Tidy integration by eliminating struct rapl and improve output formatting. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin --- tools/intel_gpu_top.c | 218 +++++++++++++++++++++++++----------------- 1 file changed, 130 insertions(+), 88 deletions(-) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 86de09aa9..0a49cfecc 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -50,10 +50,12 @@ struct pmu_pair { }; struct pmu_counter { - bool present; + uint64_t type; uint64_t config; unsigned int idx; struct pmu_pair val; + double scale; + bool present; }; struct engine { @@ -79,8 +81,8 @@ struct engines { struct pmu_pair ts; int rapl_fd; - double rapl_scale; - const char *rapl_unit; + struct pmu_counter r_gpu, r_pkg; + unsigned int num_rapl; int imc_fd; double imc_reads_scale; @@ -92,7 +94,6 @@ struct engines { struct pmu_counter freq_act; struct pmu_counter irq; struct pmu_counter rc6; - struct pmu_counter rapl; struct pmu_counter imc_reads; struct pmu_counter imc_writes; @@ -108,6 +109,109 @@ struct engines { }; +__attribute__((format(scanf,3,4))) +static int igt_sysfs_scanf(int dir, const char *attr, const char *fmt, ...) +{ + FILE *file; + int fd; + int ret = -1; + + fd = openat(dir, attr, O_RDONLY); + if (fd < 0) + return -1; + + file = fdopen(fd, "r"); + if (file) { + va_list ap; + + va_start(ap, fmt); + ret = vfscanf(file, fmt, ap); + va_end(ap); + + fclose(file); + } else { + close(fd); + } + + return ret; +} + +static int rapl_parse(struct pmu_counter *pmu, const char *str) +{ + locale_t locale, oldlocale; + bool result = true; + char buf[128] = {}; + int dir; + + dir = open("/sys/devices/power", O_RDONLY); + if (dir < 0) + return -errno; + + /* Replace user environment with plain C to match kernel format */ + locale = newlocale(LC_ALL, "C", 0); + oldlocale = uselocale(locale); + + result &= igt_sysfs_scanf(dir, "type", "%"PRIu64, &pmu->type) == 1; + + snprintf(buf, sizeof(buf) - 1, "events/energy-%s", str); + result &= igt_sysfs_scanf(dir, buf, "event=%"PRIx64, &pmu->config) == 1; + + snprintf(buf, sizeof(buf) - 1, "events/energy-%s.scale", str); + result &= igt_sysfs_scanf(dir, buf, "%lf", &pmu->scale) == 1; + + snprintf(buf, sizeof(buf) - 1, "events/energy-%s.unit", str); + if (igt_sysfs_scanf(dir, buf, "%127s", buf) == 1 && + strcmp(buf, "Joules")) + fprintf(stderr, "Unexpected units for RAPL %s: found %s\n", + str, buf); + + uselocale(oldlocale); + freelocale(locale); + + close(dir); + + if (!result) + return -EINVAL; + + if (isnan(pmu->scale) || !pmu->scale) + return -ERANGE; + + return 0; +} + +static void +rapl_open(struct pmu_counter *pmu, + const char *domain, + struct engines *engines) +{ + int fd; + + if (rapl_parse(pmu, domain) < 0) + return; + + fd = igt_perf_open_group(pmu->type, pmu->config, engines->rapl_fd); + if (fd < 0) + return; + + if (engines->rapl_fd == -1) + engines->rapl_fd = fd; + + pmu->idx = engines->num_rapl++; + pmu->present = true; +} + +static void gpu_power_open(struct pmu_counter *pmu, + struct engines *engines) +{ + rapl_open(pmu, "gpu", engines); +} + +static void pkg_power_open(struct pmu_counter *pmu, + struct engines *engines) +{ + rapl_open(pmu, "pkg", engines); +} + static uint64_t get_pmu_config(int dirfd, const char *name, const char *counter) { @@ -357,38 +461,6 @@ static double filename_to_double(const char *filename) return v; } -#define RAPL_ROOT "/sys/devices/power/" -#define RAPL_EVENT "/sys/devices/power/events/" - -static uint64_t rapl_type_id(void) -{ - return filename_to_u64(RAPL_ROOT "type", 10); -} - -static uint64_t rapl_gpu_power(void) -{ - return filename_to_u64(RAPL_EVENT "energy-gpu", 0); -} - -static double rapl_gpu_power_scale(void) -{ - return filename_to_double(RAPL_EVENT "energy-gpu.scale"); -} - -static const char *rapl_gpu_power_unit(void) -{ - char buf[32]; - - if (filename_to_buf(RAPL_EVENT "energy-gpu.unit", - buf, sizeof(buf)) == 0) - if (!strcmp(buf, "Joules")) - return strdup("Watts"); - else - return strdup(buf); - else - return NULL; -} - #define IMC_ROOT "/sys/devices/uncore_imc/" #define IMC_EVENT "/sys/devices/uncore_imc/events/" @@ -517,22 +589,9 @@ static int pmu_init(struct engines *engines) } engines->rapl_fd = -1; - if (!engines->discrete && rapl_type_id()) { - engines->rapl_scale = rapl_gpu_power_scale(); - engines->rapl_unit = rapl_gpu_power_unit(); - if (!engines->rapl_unit) - return -1; - - engines->rapl.config = rapl_gpu_power(); - if (!engines->rapl.config) - return -1; - - engines->rapl_fd = igt_perf_open(rapl_type_id(), - engines->rapl.config); - if (engines->rapl_fd < 0) - return -1; - - engines->rapl.present = true; + if (!engines->discrete) { + gpu_power_open(&engines->r_gpu, engines); + pkg_power_open(&engines->r_pkg, engines); } engines->imc_fd = -1; @@ -614,25 +673,6 @@ static void fill_str(char *buf, unsigned int bufsz, char c, unsigned int num) *buf = 0; } -static uint64_t __pmu_read_single(int fd, uint64_t *ts) -{ - uint64_t data[2] = { }; - ssize_t len; - - len = read(fd, data, sizeof(data)); - assert(len == sizeof(data)); - - if (ts) - *ts = data[1]; - - return data[0]; -} - -static uint64_t pmu_read_single(int fd) -{ - return __pmu_read_single(fd, NULL); -} - static void __update_sample(struct pmu_counter *counter, uint64_t val) { counter->val.prev = counter->val.cur; @@ -653,10 +693,6 @@ static void pmu_sample(struct engines *engines) engines->ts.prev = engines->ts.cur; - if (engines->rapl_fd >= 0) - __update_sample(&engines->rapl, - pmu_read_single(engines->rapl_fd)); - if (engines->imc_fd >= 0) { pmu_read_multi(engines->imc_fd, 2, val); update_sample(&engines->imc_reads, val); @@ -677,6 +713,12 @@ static void pmu_sample(struct engines *engines) update_sample(&engine->sema, val); update_sample(&engine->wait, val); } + + if (engines->num_rapl) { + pmu_read_multi(engines->rapl_fd, engines->num_rapl, val); + update_sample(&engines->r_gpu, val); + update_sample(&engines->r_pkg, val); + } } static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" }; @@ -1076,14 +1118,14 @@ print_header(const struct igt_device_card *card, .items = rc6_items, }; struct cnt_item power_items[] = { - { &engines->rapl, 4, 2, 1.0, t, engines->rapl_scale, "value", - "W" }, + { &engines->r_gpu, 4, 2, 1.0, t, engines->r_gpu.scale, "GPU", "gpu" }, + { &engines->r_pkg, 4, 2, 1.0, t, engines->r_pkg.scale, "Package", "pkg" }, { NULL, 0, 0, 0.0, 0.0, 0.0, "unit", "W" }, { }, }; struct cnt_group power_group = { .name = "power", - .display_name = "Power", + .display_name = "Power W", .items = power_items, }; struct cnt_group *groups[] = { @@ -1108,17 +1150,17 @@ print_header(const struct igt_device_card *card, if (lines++ < con_h) { printf("intel-gpu-top: %s - ", card->card); - if (!engines->discrete) - printf("%s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", - freq_items[1].buf, freq_items[0].buf, - rc6_items[0].buf, power_items[0].buf, - engines->rapl_unit, - irq_items[0].buf); - else - printf("%s/%s MHz; %s%% RC6; %s irqs/s\n", - freq_items[1].buf, freq_items[0].buf, - rc6_items[0].buf, irq_items[0].buf); + printf("%s/%s MHz; %s%% RC6; ", + freq_items[1].buf, freq_items[0].buf, + rc6_items[0].buf); + if (engines->r_gpu.present) { + printf("%s/%s W; ", + power_items[0].buf, + power_items[1].buf); + } + printf("%s irqs/s\n", irq_items[0].buf); } + if (lines++ < con_h) printf("\n"); } From patchwork Tue Nov 24 23:21:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 11929959 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B1FC1C56202 for ; Tue, 24 Nov 2020 23:21:44 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F24EC20BED for ; Tue, 24 Nov 2020 23:21:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F24EC20BED Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=chris-wilson.co.uk Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A0DDC6E459; Tue, 24 Nov 2020 23:21:40 +0000 (UTC) Received: from fireflyinternet.com (unknown [77.68.26.236]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7B0926E456 for ; Tue, 24 Nov 2020 23:21:38 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 23097551-1500050 for multiple; Tue, 24 Nov 2020 23:21:24 +0000 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 24 Nov 2020 23:21:22 +0000 Message-Id: <20201124232122.445431-2-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124232122.445431-1-chris@chris-wilson.co.uk> References: <20201124232122.445431-1-chris@chris-wilson.co.uk> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 2/2] tools/intel_gpu_top: Consolidate imc to use pmu_counter X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedestop.org, Chris Wilson Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Follow the same pattern as rapl for imc, and consolidate everything to work on struct pmu_counter. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin --- tools/intel_gpu_top.c | 249 ++++++++++++++---------------------------- 1 file changed, 82 insertions(+), 167 deletions(-) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 0a49cfecc..9af1c29b6 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -55,6 +55,7 @@ struct pmu_counter { unsigned int idx; struct pmu_pair val; double scale; + const char *units; bool present; }; @@ -85,17 +86,14 @@ struct engines { unsigned int num_rapl; int imc_fd; - double imc_reads_scale; - const char *imc_reads_unit; - double imc_writes_scale; - const char *imc_writes_unit; + struct pmu_counter imc_reads; + struct pmu_counter imc_writes; + unsigned int num_imc; struct pmu_counter freq_req; struct pmu_counter freq_act; struct pmu_counter irq; struct pmu_counter rc6; - struct pmu_counter imc_reads; - struct pmu_counter imc_writes; bool discrete; char *device; @@ -400,146 +398,93 @@ static struct engines *discover_engines(char *device) return engines; } -static int -filename_to_buf(const char *filename, char *buf, unsigned int bufsize) -{ - int fd, err; - ssize_t ret; - - fd = open(filename, O_RDONLY); - if (fd < 0) - return -1; - - ret = read(fd, buf, bufsize - 1); - err = errno; - close(fd); - if (ret < 1) { - errno = ret < 0 ? err : ENOMSG; - - return -1; - } +#define _open_pmu(type, cnt, pmu, fd) \ +({ \ + int fd__; \ +\ + fd__ = igt_perf_open_group((type), (pmu)->config, (fd)); \ + if (fd__ >= 0) { \ + if ((fd) == -1) \ + (fd) = fd__; \ + (pmu)->present = true; \ + (pmu)->idx = (cnt)++; \ + } \ +\ + fd__; \ +}) - if (ret > 1 && buf[ret - 1] == '\n') - buf[ret - 1] = '\0'; - else - buf[ret] = '\0'; +static int imc_parse(struct pmu_counter *pmu, const char *str) +{ + locale_t locale, oldlocale; + bool result = true; + char buf[128] = {}; + int dir; - return 0; -} + dir = open("/sys/devices/uncore_imc", O_RDONLY); + if (dir < 0) + return -errno; -static uint64_t filename_to_u64(const char *filename, int base) -{ - char buf[64], *b; + /* Replace user environment with plain C to match kernel format */ + locale = newlocale(LC_ALL, "C", 0); + oldlocale = uselocale(locale); - if (filename_to_buf(filename, buf, sizeof(buf))) - return 0; + result &= igt_sysfs_scanf(dir, "type", "%"PRIu64, &pmu->type) == 1; - /* - * Handle both single integer and key=value formats by skipping - * leading non-digits. - */ - b = buf; - while (*b && !isdigit(*b)) - b++; + snprintf(buf, sizeof(buf) - 1, "events/%s", str); + result &= igt_sysfs_scanf(dir, buf, "event=%"PRIx64, &pmu->config) == 1; - return strtoull(b, NULL, base); -} + snprintf(buf, sizeof(buf) - 1, "events/%s.scale", str); + result &= igt_sysfs_scanf(dir, buf, "%lf", &pmu->scale) == 1; -static double filename_to_double(const char *filename) -{ - char *oldlocale; - char buf[80]; - double v; + snprintf(buf, sizeof(buf) - 1, "events/%s.unit", str); + result &= igt_sysfs_scanf(dir, buf, "%127s", buf) == 1; + pmu->units = strdup(buf); - if (filename_to_buf(filename, buf, sizeof(buf))) - return 0; + uselocale(oldlocale); + freelocale(locale); - oldlocale = setlocale(LC_ALL, "C"); - v = strtod(buf, NULL); - setlocale(LC_ALL, oldlocale); + close(dir); - return v; -} + if (!result) + return -EINVAL; -#define IMC_ROOT "/sys/devices/uncore_imc/" -#define IMC_EVENT "/sys/devices/uncore_imc/events/" + if (isnan(pmu->scale) || !pmu->scale) + return -ERANGE; -static uint64_t imc_type_id(void) -{ - return filename_to_u64(IMC_ROOT "type", 10); + return 0; } -static uint64_t imc_data_reads(void) +static void +imc_open(struct pmu_counter *pmu, + const char *domain, + struct engines *engines) { - return filename_to_u64(IMC_EVENT "data_reads", 0); -} + int fd; -static double imc_data_reads_scale(void) -{ - return filename_to_double(IMC_EVENT "data_reads.scale"); -} + if (imc_parse(pmu, domain) < 0) + return; -static const char *imc_data_reads_unit(void) -{ - char buf[32]; + fd = igt_perf_open_group(pmu->type, pmu->config, engines->imc_fd); + if (fd < 0) + return; - if (filename_to_buf(IMC_EVENT "data_reads.unit", buf, sizeof(buf)) == 0) - return strdup(buf); - else - return NULL; -} + if (engines->imc_fd == -1) + engines->imc_fd = fd; -static uint64_t imc_data_writes(void) -{ - return filename_to_u64(IMC_EVENT "data_writes", 0); + pmu->idx = engines->num_imc++; + pmu->present = true; } -static double imc_data_writes_scale(void) +static void imc_writes_open(struct pmu_counter *pmu, struct engines *engines) { - return filename_to_double(IMC_EVENT "data_writes.scale"); + imc_open(pmu, "data_writes", engines); } -static const char *imc_data_writes_unit(void) +static void imc_reads_open(struct pmu_counter *pmu, struct engines *engines) { - char buf[32]; - - if (filename_to_buf(IMC_EVENT "data_writes.unit", - buf, sizeof(buf)) == 0) - return strdup(buf); - else - return NULL; + imc_open(pmu, "data_reads", engines); } -#define _open_pmu(type, cnt, pmu, fd) \ -({ \ - int fd__; \ -\ - fd__ = igt_perf_open_group((type), (pmu)->config, (fd)); \ - if (fd__ >= 0) { \ - if ((fd) == -1) \ - (fd) = fd__; \ - (pmu)->present = true; \ - (pmu)->idx = (cnt)++; \ - } \ -\ - fd__; \ -}) - -#define _open_imc(cnt, pmu, fd) \ -({ \ - int fd__; \ -\ - fd__ = igt_perf_open_group(imc_type_id(), (pmu)->config, (fd)); \ - if (fd__ >= 0) { \ - if ((fd) == -1) \ - (fd) = fd__; \ - (pmu)->present = true; \ - (pmu)->idx = (cnt)++; \ - } \ -\ - fd__; \ -}) - static int pmu_init(struct engines *engines) { unsigned int i; @@ -595,38 +540,8 @@ static int pmu_init(struct engines *engines) } engines->imc_fd = -1; - if (imc_type_id()) { - unsigned int num = 0; - - engines->imc_reads_scale = imc_data_reads_scale(); - engines->imc_writes_scale = imc_data_writes_scale(); - - engines->imc_reads_unit = imc_data_reads_unit(); - if (!engines->imc_reads_unit) - return -1; - - engines->imc_writes_unit = imc_data_writes_unit(); - if (!engines->imc_writes_unit) - return -1; - - engines->imc_reads.config = imc_data_reads(); - if (!engines->imc_reads.config) - return -1; - - engines->imc_writes.config = imc_data_writes(); - if (!engines->imc_writes.config) - return -1; - - fd = _open_imc(num, &engines->imc_reads, engines->imc_fd); - if (fd < 0) - return -1; - fd = _open_imc(num, &engines->imc_writes, engines->imc_fd); - if (fd < 0) - return -1; - - engines->imc_reads.present = true; - engines->imc_writes.present = true; - } + imc_reads_open(&engines->imc_reads, engines); + imc_writes_open(&engines->imc_writes, engines); return 0; } @@ -692,13 +607,6 @@ static void pmu_sample(struct engines *engines) unsigned int i; engines->ts.prev = engines->ts.cur; - - if (engines->imc_fd >= 0) { - pmu_read_multi(engines->imc_fd, 2, val); - update_sample(&engines->imc_reads, val); - update_sample(&engines->imc_writes, val); - } - engines->ts.cur = pmu_read_multi(engines->fd, num_val, val); update_sample(&engines->freq_req, val); @@ -719,6 +627,12 @@ static void pmu_sample(struct engines *engines) update_sample(&engines->r_gpu, val); update_sample(&engines->r_pkg, val); } + + if (engines->num_imc) { + pmu_read_multi(engines->imc_fd, engines->num_imc, val); + update_sample(&engines->imc_reads, val); + update_sample(&engines->imc_writes, val); + } } static const char *bars[] = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" }; @@ -1172,9 +1086,9 @@ static int print_imc(struct engines *engines, double t, int lines, int con_w, int con_h) { struct cnt_item imc_items[] = { - { &engines->imc_reads, 6, 0, 1.0, t, engines->imc_reads_scale, + { &engines->imc_reads, 6, 0, 1.0, t, engines->imc_reads.scale, "reads", "rd" }, - { &engines->imc_writes, 6, 0, 1.0, t, engines->imc_writes_scale, + { &engines->imc_writes, 6, 0, 1.0, t, engines->imc_writes.scale, "writes", "wr" }, { NULL, 0, 0, 0.0, 0.0, 0.0, "unit" }, { }, @@ -1189,12 +1103,15 @@ print_imc(struct engines *engines, double t, int lines, int con_w, int con_h) }; int ret; + if (!engines->num_imc) + return lines; + ret = asprintf((char **)&imc_group.display_name, "IMC %s/s", - engines->imc_reads_unit); + engines->imc_reads.units); assert(ret >= 0); ret = asprintf((char **)&imc_items[2].unit, "%s/s", - engines->imc_reads_unit); + engines->imc_reads.units); assert(ret >= 0); print_groups(groups); @@ -1205,11 +1122,11 @@ print_imc(struct engines *engines, double t, int lines, int con_w, int con_h) if (output_mode == INTERACTIVE) { if (lines++ < con_h) printf(" IMC reads: %s %s/s\n", - imc_items[0].buf, engines->imc_reads_unit); + imc_items[0].buf, engines->imc_reads.units); if (lines++ < con_h) printf(" IMC writes: %s %s/s\n", - imc_items[1].buf, engines->imc_writes_unit); + imc_items[1].buf, engines->imc_writes.units); if (lines++ < con_h) printf("\n"); @@ -1509,9 +1426,7 @@ int main(int argc, char **argv) t, lines, con_w, con_h, &consumed); - if (engines->imc_fd) - lines = print_imc(engines, t, lines, con_w, - con_h); + lines = print_imc(engines, t, lines, con_w, con_h); lines = print_engines_header(engines, t, lines, con_w, con_h);