From 567c63e7faed9cfdd2cb7fe8cdcb764024f7ebe9 Mon Sep 17 00:00:00 2001 From: Vineet Kumar Maheshwari Date: Tue, 21 Mar 2023 11:43:38 +0530 Subject: [PATCH] Avoid PrioritizedSplitRunner CPU user time overhead --- .../executor/PrioritizedSplitRunner.java | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/presto-main/src/main/java/io/prestosql/execution/executor/PrioritizedSplitRunner.java b/presto-main/src/main/java/io/prestosql/execution/executor/PrioritizedSplitRunner.java index c9ad9c098..e3d8e3bc8 100644 --- a/presto-main/src/main/java/io/prestosql/execution/executor/PrioritizedSplitRunner.java +++ b/presto-main/src/main/java/io/prestosql/execution/executor/PrioritizedSplitRunner.java @@ -18,11 +18,13 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import io.airlift.log.Logger; import io.airlift.stats.CounterStat; -import io.airlift.stats.CpuTimer; +import io.airlift.stats.CpuTimer.CpuDuration; import io.airlift.stats.TimeStat; import io.airlift.units.Duration; import io.prestosql.execution.SplitRunner; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; @@ -30,6 +32,7 @@ import java.util.concurrent.atomic.AtomicReference; import static io.prestosql.operator.Operator.NOT_BLOCKED; import static java.lang.String.format; +import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.NANOSECONDS; public class PrioritizedSplitRunner @@ -159,15 +162,17 @@ public class PrioritizedSplitRunner waitNanos.getAndAdd(startNanos - lastReady.get()); - CpuTimer timer = new CpuTimer(); + // Do not collect user vs system components of CPU time since it's more expensive and not used here + CpuTimer timer = new CpuTimer(ticker); ListenableFuture blocked = split.processFor(SPLIT_RUN_QUANTA); - CpuTimer.CpuDuration elapsed = timer.elapsedTime(); + CpuDuration elapsed = timer.elapsedTime(); - long quantaScheduledNanos = ticker.read() - startNanos; + long endNanos = ticker.read(); + long quantaScheduledNanos = endNanos - startNanos; scheduledNanos.addAndGet(quantaScheduledNanos); priority.set(taskHandle.addScheduledNanos(quantaScheduledNanos)); - lastRun.set(ticker.read()); + lastRun.set(endNanos); if (blocked == NOT_BLOCKED) { unblockedQuantaWallTime.add(elapsed.getWall()); @@ -263,4 +268,34 @@ public class PrioritizedSplitRunner { return format("Split %-15s-%d", taskHandle.getTaskId(), splitId); } + + private static class CpuTimer + { + private static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean(); + + private final Ticker ticker; + private final long wallStartTime; + private final long cpuStartTime; + + public CpuTimer(Ticker ticker) + { + this.ticker = requireNonNull(ticker, "ticker is null"); + this.wallStartTime = ticker.read(); + this.cpuStartTime = THREAD_MX_BEAN.getCurrentThreadCpuTime(); + } + + public io.airlift.stats.CpuTimer.CpuDuration elapsedTime() + { + long currentWallTime = ticker.read(); + long currentCpuTime = THREAD_MX_BEAN.getCurrentThreadCpuTime(); + return new io.airlift.stats.CpuTimer.CpuDuration(nanosBetween(wallStartTime, currentWallTime), + nanosBetween(cpuStartTime, currentCpuTime), + null); + } + + private static Duration nanosBetween(long start, long end) + { + return new Duration(Math.abs(end - start), NANOSECONDS); + } + } } -- Gitee