Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp10895rwr; Thu, 4 May 2023 14:02:26 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ64o+fdEkNL6T4xoTd7Wx7bygMlheaULcZU3KJ3IZiUZqs8nYHzWU65r+2bnNB4GU3vjDjB X-Received: by 2002:a05:6a00:3698:b0:643:6fd8:ea7a with SMTP id dw24-20020a056a00369800b006436fd8ea7amr4082527pfb.16.1683234145838; Thu, 04 May 2023 14:02:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683234145; cv=none; d=google.com; s=arc-20160816; b=0u4oWH2IYkOMF5I6ScVbKBn9dMHUvXE6BGfnpcGMWr+W+o4Sh6oQKwryzNotG6bWIo QjN0lGOoT1PCjm2GlUSyCPHa04XFDOXaZ2YH1rY1FxFc/Rs0KCrxjIHwIxnIjCqv7t10 go+8b0//+RNPgLAQjQ/2Edb+kuAWrlHKBOUUSwxUz3oEdsiW5BlO5F6P4MKHf1cOqEef 6ZoeON2aGaFDBCzTlhrE5HguIwIlgpUTMpvS6tbRyQnL5dggeFrnWApeHuzg6xdubE3h eolsJCbKsuZtrjDPmt3GTSEftAM0c869wIJEZs63w5HWf7kfR+qReanIbd65Rr+k2jCm rCoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:mime-version:message-id:date :dkim-signature; bh=/r9KGpkW5PSBM9D941BUL0+gJYwAE5n4IR7E5or+wxM=; b=oBOm3HjAFZ/wPo5Jx77DSbrH+A6GiysD9Y7kTmWehkk4BoFvUC06A+QSVwlidLFgzK uuVVqg5V27LBi67DEaT5q5u07QyRtDDYCF42xzlJIsLVKwiP15VkD4MA10lJyve9EV3A rprqRbr2NE7GS1MZSgzDxB6vl1VNOFATD2WFlFCs5R2CaseDkAS48eYwoChoopKflYGO tXF9Me2t1P9ALbVCGfMZxiU7qO23ut8se3RTyiMUaR9cvFPjsFWe9wHnvyEw0Sh9a+kA Wic6g/8KyPeS5BnKLBhXI23M5d3wpeuojxkt7z2WmDMQdBSu1kzmBhZ2rPGJnTmLhRi1 0R+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=A+F+1nGk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f7-20020aa79d87000000b0063b834cf20esi297579pfq.91.2023.05.04.14.02.12; Thu, 04 May 2023 14:02:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=A+F+1nGk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232598AbjEDUVd (ORCPT + 99 others); Thu, 4 May 2023 16:21:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230169AbjEDUVM (ORCPT ); Thu, 4 May 2023 16:21:12 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC31A281B6 for ; Thu, 4 May 2023 13:07:08 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id d2e1a72fcca58-6439cf8d6faso98591b3a.1 for ; Thu, 04 May 2023 13:07:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1683230757; x=1685822757; h=cc:to:from:subject:mime-version:message-id:date:from:to:cc:subject :date:message-id:reply-to; bh=/r9KGpkW5PSBM9D941BUL0+gJYwAE5n4IR7E5or+wxM=; b=A+F+1nGkKZNvXnCdhaSW0gZ2uEJuFYqqUUdbC3zWxTYzxgX6KVINf2otMJ8dqWRt99 NKXrSOy62iASlHDMPWp19rygyNrbD6ndINRinFfJxJH1mqwtIk6wuiPvRwSjxpHcxl+H enjOC846aQGQXd3grzYaU7lM3JkgU3GWh10DyisJ9nxEexeZ4vTQNYImFY8V0KK4m7eN 9ygmebTC9TU7jt80un3GIL0BtT56peh96lplLuDtYgdpzh4MrAB4v6jebrM93a5rhx2o 1jwCB1lKAzqETCC5st9b0TuTeukiuyLOwVKZUXk8slTGaQhH/kDORhKh7qoKGF0KBnNf 05cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683230757; x=1685822757; h=cc:to:from:subject:mime-version:message-id:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=/r9KGpkW5PSBM9D941BUL0+gJYwAE5n4IR7E5or+wxM=; b=LKw0OOahsAf1+vtVLyJXSMocz9sDnV5eHDcJCyoe8OJ00I+9WsPztUDdr7mB0Ltr7k pI/sieV99fQJNeKxrH9OO8tBZ/POnkUspY0PSE7bD2W8PunkrCDiGh3WAVbrEbwEdC+n RYucdkkLrOhTAFsg6IXnJrzqlQV3y1qOINuhn9ZCFMDt9lFL4gBHJEVEzRG+kRAV70Xk KpDj6fn0D0Hs47e1MwMNgJ4Niz+3sgws2hu93vU2SpxGAJWY6dvgaYtSCD5pc5PKyVR9 sYyooG+LLRWBWO029+zr4CWjNE3ANGalCfF8HsZEo4/gCsN4iKuDGKiMpd1KUXvJKKiO ES1w== X-Gm-Message-State: AC+VfDxyEJZ1YPafNFl3JC3UEWXefcEuQilXFbkViLXv0QNBa6WChEPk qRStt+9Z2Oz9l9nkYPmRVN3ese0a7uc8 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:3367:2fed:395f:6f64]) (user=irogers job=sendgmr) by 2002:a05:6902:1804:b0:b9d:c27c:3442 with SMTP id cf4-20020a056902180400b00b9dc27c3442mr452307ybb.9.1683230294858; Thu, 04 May 2023 12:58:14 -0700 (PDT) Date: Thu, 4 May 2023 12:58:02 -0700 Message-Id: <20230504195803.3331775-1-irogers@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.40.1.521.gf1e218fcd8-goog Subject: [PATCH v1 1/2] perf expr: Make the evaluation of & and | logical and lazy From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Adrian Hunter , James Clark , Kan Liang , Andrii Nakryiko , Eduard Zingerman , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Ahmad Yasin , Stephane Eranian , Andi Kleen , Perry Taylor , Samantha Alt , Caleb Biggers , Weilin Wang , Edward Baker Cc: Ian Rogers Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently the & and | operators are only used in metric thresholds like (from the tma_retiring metric): tma_retiring > 0.7 | tma_heavy_operations > 0.1 Thresholds are always computed when present, but a lack events may mean the threshold can't be computed. This happens with the option --metric-no-threshold for say the metric tma_retiring on Tigerlake model CPUs. To fully compute the threshold tma_heavy_operations is needed and it needs the extra events of IDQ.MS_UOPS, UOPS_DECODED.DEC0, cpu/UOPS_DECODED.DEC0,cmask=1/ and IDQ.MITE_UOPS. So --metric-no-threshold is a useful option to reduce the number of events needed and potentially multiplexing of events. Rather than just fail threshold computations like this, we may know a result from just the left or right-hand side. So, for tma_retiring if its value is "> 0.7" we know it is over the threshold. This allows the metric to have the threshold coloring, when possible, without all the counters being programmed. Signed-off-by: Ian Rogers --- tools/perf/tests/expr.c | 40 +++++++++++++++++++ tools/perf/util/expr.y | 86 +++++++++++++++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 17 deletions(-) diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index cbf0e0c74906..45c7fedb797a 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -184,6 +184,46 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u NULL, ctx) == 0); TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + /* The expression is a constant 0.0 without needing to evaluate EVENT1. */ + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("0 & EVENT1 > 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("EVENT1 > 0 & 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("1 & EVENT1 > 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1", &val_ptr)); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("EVENT1 > 0 & 1", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1", &val_ptr)); + + /* The expression is a constant 1.0 without needing to evaluate EVENT1. */ + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("1 | EVENT1 > 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("EVENT1 > 0 | 1", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("0 | EVENT1 > 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1", &val_ptr)); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("EVENT1 > 0 | 0", NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1", &val_ptr)); + /* Test toplogy constants appear well ordered. */ expr__ctx_clear(ctx); TEST_ASSERT_VAL("#num_cpus", expr__parse(&num_cpus, ctx, "#num_cpus") == 0); diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 250e444bf032..6b110f9f95c9 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -123,20 +123,6 @@ static struct ids handle_id(struct expr_parse_ctx *ctx, char *id, * constant value using OP. Its invariant that there are no ids. If computing * ids for non-constants union the set of IDs that must be computed. */ -#define BINARY_LONG_OP(RESULT, OP, LHS, RHS) \ - if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \ - assert(LHS.ids == NULL); \ - assert(RHS.ids == NULL); \ - if (isnan(LHS.val) || isnan(RHS.val)) { \ - RESULT.val = NAN; \ - } else { \ - RESULT.val = (long)LHS.val OP (long)RHS.val; \ - } \ - RESULT.ids = NULL; \ - } else { \ - RESULT = union_expr(LHS, RHS); \ - } - #define BINARY_OP(RESULT, OP, LHS, RHS) \ if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \ assert(LHS.ids == NULL); \ @@ -213,9 +199,75 @@ expr: NUMBER } | ID { $$ = handle_id(ctx, $1, compute_ids, /*source_count=*/false); } | SOURCE_COUNT '(' ID ')' { $$ = handle_id(ctx, $3, compute_ids, /*source_count=*/true); } -| expr '|' expr { BINARY_LONG_OP($$, |, $1, $3); } -| expr '&' expr { BINARY_LONG_OP($$, &, $1, $3); } -| expr '^' expr { BINARY_LONG_OP($$, ^, $1, $3); } +| expr '|' expr +{ + if (is_const($1.val) && is_const($3.val)) { + assert($1.ids == NULL); + assert($3.ids == NULL); + $$.ids = NULL; + $$.val = (fpclassify($1.val) == FP_ZERO && fpclassify($3.val) == FP_ZERO) ? 0 : 1; + } else if (is_const($1.val)) { + assert($1.ids == NULL); + if (fpclassify($1.val) == FP_ZERO) { + $$ = $3; + } else { + $$.val = 1; + $$.ids = NULL; + ids__free($3.ids); + } + } else if (is_const($3.val)) { + assert($3.ids == NULL); + if (fpclassify($3.val) == FP_ZERO) { + $$ = $1; + } else { + $$.val = 1; + $$.ids = NULL; + ids__free($1.ids); + } + } else { + $$ = union_expr($1, $3); + } +} +| expr '&' expr +{ + if (is_const($1.val) && is_const($3.val)) { + assert($1.ids == NULL); + assert($3.ids == NULL); + $$.val = (fpclassify($1.val) != FP_ZERO && fpclassify($3.val) != FP_ZERO) ? 1 : 0; + $$.ids = NULL; + } else if (is_const($1.val)) { + assert($1.ids == NULL); + if (fpclassify($1.val) != FP_ZERO) { + $$ = $3; + } else { + $$.val = 0; + $$.ids = NULL; + ids__free($3.ids); + } + } else if (is_const($3.val)) { + assert($3.ids == NULL); + if (fpclassify($3.val) != FP_ZERO) { + $$ = $1; + } else { + $$.val = 0; + $$.ids = NULL; + ids__free($1.ids); + } + } else { + $$ = union_expr($1, $3); + } +} +| expr '^' expr +{ + if (is_const($1.val) && is_const($3.val)) { + assert($1.ids == NULL); + assert($3.ids == NULL); + $$.val = (fpclassify($1.val) == FP_ZERO) != (fpclassify($3.val) == FP_ZERO) ? 1 : 0; + $$.ids = NULL; + } else { + $$ = union_expr($1, $3); + } +} | expr '<' expr { BINARY_OP($$, <, $1, $3); } | expr '>' expr { BINARY_OP($$, >, $1, $3); } | expr '+' expr { BINARY_OP($$, +, $1, $3); } -- 2.40.1.521.gf1e218fcd8-goog