/** * **************************************************************************** * Copyright (c) 2010-2016 by Min Cai (min.cai.china@gmail.com). * <p> * This file is part of the Archimulator multicore architectural simulator. * <p> * Archimulator is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * <p> * Archimulator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * <p> * You should have received a copy of the GNU General Public License * along with Archimulator. If not, see <http://www.gnu.org/licenses/>. * **************************************************************************** */ package archimulator.uncore.cache.Interval; import archimulator.common.Simulation; import archimulator.common.SimulationType; import archimulator.common.report.ReportNode; import archimulator.common.report.Reportable; import archimulator.core.Thread; import archimulator.core.event.DynamicInstructionCommittedEvent; import archimulator.uncore.helperThread.HelperThreadL2RequestProfilingHelper; import archimulator.uncore.helperThread.HelperThreadingHelper; import archimulator.uncore.mlp.BLPProfilingHelper; import archimulator.uncore.mlp.MLPProfilingHelper; import java.util.ArrayList; import java.util.List; /** * Interval helper. * * @author Min Cai */ public class IntervalHelper implements Reportable { /** * Interval. */ private class Interval { private long numMainThreadDynamicInstructionsCommitted; private long numHelperThreadDynamicInstructionsCommitted; private long numMainThreadL2Hits; private long numMainThreadL2Misses; private long numHelperThreadL2Hits; private long numHelperThreadL2Misses; private long numRedundantHitToTransientTagHelperThreadL2Requests; private long numRedundantHitToCacheHelperThreadL2Requests; private long numTimelyHelperThreadL2Requests; private long numLateHelperThreadL2Requests; private long numBadHelperThreadL2Requests; private long numEarlyHelperThreadL2Requests; private long numUglyHelperThreadL2Requests; private double mainThreadIpc; private double helperThreadIpc; private double mainThreadCpi; private double helperThreadCpi; private double mainThreadMpki; private double helperThreadMpki; private double l2MissMlpCosts; private double numL2MissMlpSamples; private double dramBankAccessBlpCosts; private double numDramBankAccessBlpSamples; /** * Handle when this interval is completed. */ public void onCompleted() { mainThreadIpc = (double) numMainThreadDynamicInstructionsCommitted / numCyclesElapsedPerInterval; helperThreadIpc = (double) numHelperThreadDynamicInstructionsCommitted / numCyclesElapsedPerInterval; mainThreadCpi = (double) numCyclesElapsedPerInterval / numMainThreadDynamicInstructionsCommitted; helperThreadCpi = (double) numCyclesElapsedPerInterval / numHelperThreadDynamicInstructionsCommitted; mainThreadMpki = (double) numMainThreadL2Misses / ((double) numMainThreadDynamicInstructionsCommitted / 1000); helperThreadMpki = (double) numHelperThreadL2Misses / ((double) numHelperThreadDynamicInstructionsCommitted / 1000); } } private int numCyclesElapsedPerInterval; private int numCyclesElapsed; private List<Interval> intervals; private Interval currentInterval; /** * Create an interval helper. * * @param simulation the simulation */ public IntervalHelper(final Simulation simulation) { this.numCyclesElapsedPerInterval = 5000000; this.intervals = new ArrayList<>(); this.currentInterval = new Interval(); simulation.getCycleAccurateEventQueue().getPerCycleEvents().add(() -> { if (simulation.getType() != SimulationType.FAST_FORWARD) { numCyclesElapsed++; if (numCyclesElapsed == numCyclesElapsedPerInterval) { currentInterval.onCompleted(); intervals.add(currentInterval); numCyclesElapsed = 0; currentInterval = new Interval(); } } }); simulation.getBlockingEventDispatcher().addListener(DynamicInstructionCommittedEvent.class, event -> { Thread thread = event.getDynamicInstruction().getThread(); if (HelperThreadingHelper.isMainThread(thread)) { currentInterval.numMainThreadDynamicInstructionsCommitted++; } else if (HelperThreadingHelper.isHelperThread(thread)) { currentInterval.numHelperThreadDynamicInstructionsCommitted++; } }); simulation.getBlockingEventDispatcher().addListener(HelperThreadL2RequestProfilingHelper.MainThreadL2HitEvent.class, event -> { currentInterval.numMainThreadL2Hits++; }); simulation.getBlockingEventDispatcher().addListener(HelperThreadL2RequestProfilingHelper.MainThreadL2MissEvent.class, event -> { currentInterval.numMainThreadL2Misses++; }); simulation.getBlockingEventDispatcher().addListener(HelperThreadL2RequestProfilingHelper.HelperThreadL2HitEvent.class, event -> { currentInterval.numHelperThreadL2Hits++; }); simulation.getBlockingEventDispatcher().addListener(HelperThreadL2RequestProfilingHelper.HelperThreadL2MissEvent.class, event -> { currentInterval.numHelperThreadL2Misses++; }); simulation.getBlockingEventDispatcher().addListener(HelperThreadL2RequestProfilingHelper.HelperThreadL2RequestEvent.class, event -> { switch (event.getQuality()) { case REDUNDANT_HIT_TO_TRANSIENT_TAG: currentInterval.numRedundantHitToTransientTagHelperThreadL2Requests++; break; case REDUNDANT_HIT_TO_CACHE: currentInterval.numRedundantHitToCacheHelperThreadL2Requests++; break; case TIMELY: currentInterval.numTimelyHelperThreadL2Requests++; break; case LATE: currentInterval.numLateHelperThreadL2Requests++; break; case BAD: currentInterval.numBadHelperThreadL2Requests++; break; case EARLY: currentInterval.numEarlyHelperThreadL2Requests++; break; case UGLY: currentInterval.numUglyHelperThreadL2Requests++; break; default: throw new IllegalArgumentException(); } }); simulation.getBlockingEventDispatcher().addListener(MLPProfilingHelper.L2MissMLPProfiledEvent.class, event -> { currentInterval.l2MissMlpCosts += event.getPendingL2Miss().getMlpCost(); currentInterval.numL2MissMlpSamples++; }); simulation.getBlockingEventDispatcher().addListener(BLPProfilingHelper.BankAccessBLPProfiledEvent.class, event -> { currentInterval.dramBankAccessBlpCosts += event.getPendingDramBankAccess().getBlpCost(); currentInterval.numDramBankAccessBlpSamples++; }); } @Override public void dumpStats(ReportNode reportNode) { reportNode.getChildren().add(new ReportNode(reportNode, "intervalHelper") {{ for (int i = 0; i < intervals.size(); i++) { Interval interval = intervals.get(i); getChildren().add( new ReportNode( this, String.format("numMainThreadDynamicInstructionsCommitted/%d", i), String.format("%d", interval.numMainThreadDynamicInstructionsCommitted) ) ); getChildren().add( new ReportNode( this, String.format("numHelperThreadDynamicInstructionsCommitted/%d", i), String.format("%d", interval.numHelperThreadDynamicInstructionsCommitted) ) ); getChildren().add( new ReportNode( this, String.format("numMainThreadL2Hits/%d", i), String.format("%d", interval.numMainThreadL2Hits) ) ); getChildren().add( new ReportNode( this, String.format("numMainThreadL2Misses/%d", i), String.format("%d", interval.numMainThreadL2Misses) ) ); getChildren().add( new ReportNode( this, String.format("numHelperThreadL2Hits/%d", i), String.format("%d", interval.numHelperThreadL2Hits) ) ); getChildren().add( new ReportNode( this, String.format("numHelperThreadL2Misses/%d", i), String.format("%d", interval.numHelperThreadL2Misses) ) ); getChildren().add( new ReportNode( this, String.format("numRedundantHitToTransientTagHelperThreadL2Requests/%d", i), String.format("%d", interval.numRedundantHitToTransientTagHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numRedundantHitToCacheHelperThreadL2Requests/%d", i), String.format("%d", interval.numRedundantHitToCacheHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numTimelyHelperThreadL2Requests/%d", i), String.format("%d", interval.numTimelyHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numLateHelperThreadL2Requests/%d", i), String.format("%d", interval.numLateHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numBadHelperThreadL2Requests/%d", i), String.format("%d", interval.numBadHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numEarlyHelperThreadL2Requests/%d", i), String.format("%d", interval.numEarlyHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("numUglyHelperThreadL2Requests/%d", i), String.format("%d", interval.numUglyHelperThreadL2Requests) ) ); getChildren().add( new ReportNode( this, String.format("mainThreadIpc/%d", i), String.format("%s", interval.mainThreadIpc) ) ); getChildren().add( new ReportNode( this, String.format("helperThreadIpc/%d", i), String.format("%s", interval.helperThreadIpc) ) ); getChildren().add( new ReportNode( this, String.format("mainThreadCpi/%d", i), String.format("%s", interval.mainThreadCpi) ) ); getChildren().add( new ReportNode( this, String.format("helperThreadCpi/%d", i), String.format("%s", interval.helperThreadCpi) ) ); getChildren().add( new ReportNode( this, String.format("mainThreadMpki/%d", i), String.format("%s", interval.mainThreadMpki) ) ); getChildren().add( new ReportNode( this, String.format("helperThreadMpki/%d", i), String.format("%s", interval.helperThreadMpki) ) ); getChildren().add( new ReportNode( this, String.format("averageL2MissMlpCost/%d", i), String.format( "%s", interval.numL2MissMlpSamples == 0 ? 0 : interval.l2MissMlpCosts / interval.numL2MissMlpSamples ) ) ); getChildren().add( new ReportNode( this, String.format("numL2MissMlpSamples/%d", i), String.format("%s", interval.numL2MissMlpSamples) ) ); getChildren().add( new ReportNode( this, String.format("averageDramBankAccessBlpCost/%d", i), String.format( "%s", interval.numDramBankAccessBlpSamples == 0 ? 0 : interval.dramBankAccessBlpCosts / interval.numDramBankAccessBlpSamples ) ) ); getChildren().add( new ReportNode( this, String.format("numDramBankAccessBlpSamples/%d", i), String.format("%s", interval.numDramBankAccessBlpSamples) ) ); } }}); } }