/** * **************************************************************************** * 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.noc; import archimulator.common.*; import archimulator.common.report.ReportNode; import archimulator.common.report.Reportable; import archimulator.uncore.AbstractMemoryHierarchy; import archimulator.uncore.MemoryDevice; import archimulator.uncore.Net; import archimulator.uncore.coherence.msi.controller.L1IController; import archimulator.uncore.noc.routers.FlitState; import archimulator.uncore.noc.prediction.RouterCongestionStatusPredictionHelper; import archimulator.util.event.BlockingEvent; import archimulator.util.event.BlockingEventDispatcher; import archimulator.util.event.CycleAccurateEventQueue; import java.util.HashMap; import java.util.Map; import java.util.Random; /** * NoC memory hierarchy. * * @author Min Cai */ public class NoCMemoryHierarchy extends AbstractMemoryHierarchy implements Net, NoCEnvironment, Reportable { private Network network; private RouterCongestionStatusPredictionHelper routerCongestionStatusPredictionHelper; private Map<SimulationObject, Integer> devicesToNodeIds; private Random random; /** * Create a basic memory hierarchy. * * @param experiment the experiment * @param simulation the simulation * @param blockingEventDispatcher the blocking event dispatcher * @param cycleAccurateEventQueue the cycle accurate event queue */ public NoCMemoryHierarchy(CPUExperiment experiment, Simulation simulation, BlockingEventDispatcher<BlockingEvent> blockingEventDispatcher, CycleAccurateEventQueue cycleAccurateEventQueue) { super(experiment, simulation, blockingEventDispatcher, cycleAccurateEventQueue); this.devicesToNodeIds = new HashMap<>(); int i = 0; for (L1IController l1IController : this.getL1IControllers()) { this.devicesToNodeIds.put(l1IController, i); this.devicesToNodeIds.put( this.getL1DControllers().get( this.getL1IControllers().indexOf(l1IController) ), i); i++; } this.devicesToNodeIds.put(this.getL2Controller(), i); i++; this.devicesToNodeIds.put(this.getMemoryController(), i); i++; int width = (int) Math.sqrt(i); if (width * width != i) { i = (width + 1) * (width + 1); } this.network = NetworkFactory.create(this, this.getCycleAccurateEventQueue(), i); this.routerCongestionStatusPredictionHelper = new RouterCongestionStatusPredictionHelper(this.network); this.getExperiment().getConfig().setMaxInputBufferSize(this.getL2Controller().getCache().getLineSize() + 8); this.random = this.getExperiment().getConfig().getRandSeed() != -1 ? new Random(this.getExperiment().getConfig().getRandSeed()) : new Random(); } /** * Get the net for the specified source and destination devices. * * @param from the source device * @param to the destination device * @return the net for the specified source and destination devices */ @Override public Net getNet(MemoryDevice from, MemoryDevice to) { return this; } /** * Transfer a message of the specified size from the source device to the destination device. * * @param deviceFrom the source device * @param deviceTo the destination device * @param size the size * @param onCompletedCallback the callback action performed when the transfer is completed */ @Override public void transfer(MemoryDevice deviceFrom, MemoryDevice deviceTo, int size, Runnable onCompletedCallback) { int src = this.devicesToNodeIds.get(deviceFrom); int dest = this.devicesToNodeIds.get(deviceTo); DataPacket packet = new DataPacket(this.network, src, dest, size, onCompletedCallback); this.getCycleAccurateEventQueue().schedule(this, () -> this.network.receive(packet), 1); } /** * Dump the statistics into the specified report node. * * @param reportNode the report node */ @Override public void dumpStats(ReportNode reportNode) { reportNode.getChildren().add(new ReportNode(reportNode, getName()) {{ routerCongestionStatusPredictionHelper.dumpStats(this); getChildren().add( new ReportNode( this, "noc/numPacketsReceived", String.format("%d", network.getNumPacketsReceived()) ) ); getChildren().add( new ReportNode( this, "noc/numPacketsTransmitted", String.format("%d", network.getNumPacketsTransmitted()) ) ); getChildren().add( new ReportNode( this, "noc/throughput", String.format("%s", network.throughput()) ) ); getChildren().add( new ReportNode( this, "noc/averagePacketDelay", String.format("%s", network.averagePacketDelay()) ) ); getChildren().add( new ReportNode( this, "noc/averagePacketHops", String.format("%s", network.averagePacketHops()) ) ); getChildren().add( new ReportNode( this, "noc/maxPacketDelay", String.format("%d", network.getMaxPacketDelay()) ) ); getChildren().add( new ReportNode( this, "noc/maxPacketHops", String.format("%d", network.getMaxPacketHops()) ) ); getChildren().add( new ReportNode( this, "noc/numPayloadPacketsReceived", String.format("%d", network.getNumPayloadPacketsReceived()) ) ); getChildren().add( new ReportNode( this, "noc/numPayloadPacketsTransmitted", String.format("%d", network.getNumPayloadPacketsTransmitted()) ) ); getChildren().add( new ReportNode( this, "noc/payloadThroughput", String.format("%s", network.payloadThroughput()) ) ); getChildren().add( new ReportNode( this, "noc/averagePayloadPacketDelay", String.format("%s", network.averagePayloadPacketDelay()) ) ); getChildren().add( new ReportNode( this, "noc/averagePayloadPacketHops", String.format("%s", network.averagePayloadPacketHops()) ) ); getChildren().add( new ReportNode( this, "noc/maxPayloadPacketDelay", String.format("%d", network.getMaxPayloadPacketDelay()) ) ); getChildren().add( new ReportNode( this, "noc/maxPayloadPacketHops", String.format("%d", network.getMaxPayloadPacketHops()) ) ); for(FlitState state : FlitState.values()) { getChildren().add( new ReportNode( this, String.format("noc/averageFlitPerStateDelay::%s", state), String.format("%s", network.averageFlitPerStateDelay(state)) ) ); } for(FlitState state : FlitState.values()) { getChildren().add( new ReportNode( this, String.format("noc/maxFlitPerStateDelay::%s", state), network.getMaxFlitPerStateDelay().containsKey(state) ? String.format("%d", network.getMaxFlitPerStateDelay().get(state)) : String.format("%s", 0.0) ) ); } }}); } /** * Get the name of the memory hierarchy. * * @return the name of the memory hierarchy */ @Override public String getName() { return "net"; } /** * Get the config. * * @return the config */ @Override public NoCConfig getConfig() { return getExperiment().getConfig(); } /** * Get the random. * * @return the random */ @Override public Random getRandom() { return random; } /** * Get a boolean value indicating whether it is currently in the detailed simulation mode or not. * * @return a boolean value indicating whether it is currently in the detailed simulation mode or not */ @Override public boolean isInDetailedSimulationMode() { return this.getSimulation().getType() == SimulationType.MEASUREMENT || this.getSimulation().getType() == SimulationType.WARMUP; } /** * Get the network. * * @return the network */ public Network getNetwork() { return network; } }