Example #1
0
        protected void statsEjectFlit(Flit f)
        {
            // Keep track of how many packets get ejected
            ejectPacketCount++; // actually eject flit count

            // per-flit latency stats
            ulong net_latency   = Simulator.CurrentRound - f.injectionTime;
            ulong total_latency = Simulator.CurrentRound - f.packet.creationTime;
            ulong inj_latency   = total_latency - net_latency;

#if DEBUG
            Console.WriteLine("Cycle: {2} PID: {0} FID: {1} | EJECT Coord ({4},{5}) createTime {3}",
                              f.packet.ID, f.flitNr, Simulator.CurrentRound, f.packet.injectionTime, coord.x, coord.y);
#endif

            Simulator.stats.flit_inj_latency.Add(inj_latency);
            Simulator.stats.flit_net_latency.Add(net_latency);

            // A rough estimate of number of cycles it would take for a flit to go
            Simulator.stats.flit_net_latency_alone_byreqID[f.packet.requesterID].Add(
                (int)Simulator.distance(f.packet.src, f.packet.dest) * Config.router.linkLatency);
            // Record the net latency for each requester to take care of data reply from random sources
            Simulator.stats.flit_net_latency_byreqID[f.packet.requesterID].Add(net_latency);

            Simulator.stats.mshrThrottle_flit_net_latency.Add(net_latency);
            Simulator.stats.flit_total_latency.Add(inj_latency);

            Simulator.stats.eject_flit.Add();
            Simulator.stats.eject_flit_bydest[f.packet.dest.ID].Add();
            int id = f.packet.dest.ID;
            // Collect stats on my own data reply only
            if (id == f.packet.requesterID)
            {
                Simulator.stats.eject_flit_myReply[id].Add();
            }

            Simulator.stats.eject_flit_byreqID[f.packet.requesterID].Add();

            int minpath = Math.Abs(f.packet.dest.x - f.packet.src.x) + Math.Abs(f.packet.dest.y - f.packet.src.y);
            Simulator.stats.minpath.Add(minpath);
            Simulator.stats.minpath_bysrc[f.packet.src.ID].Add(minpath);

            //f.dumpDeflections();
            Simulator.stats.deflect_perdist[f.distance].Add(f.nrOfDeflections);
            if (f.nrOfDeflections != 0)
            {
                Simulator.stats.deflect_perflit_byreq[f.packet.requesterID].Add(f.nrOfDeflections);
            }
        }
Example #2
0
        // closest out of 'nodes' set
        int closest(int node, CmpCache_Owners nodes)
        {
            int   best      = -1;
            int   best_dist = m_N;
            Coord here      = new Coord(node);

            for (int i = 0; i < m_N; i++)
            {
                if (nodes.is_set(i))
                {
                    int dist = (int)Simulator.distance(new Coord(i), here);
                    if (dist < best_dist)
                    {
                        best      = i;
                        best_dist = dist;
                    }
                }
            }

            return(best);
        }
Example #3
0
        protected override void _doStep()
        {
            stepNacks();
            /* bool ejectedThisCycle = */ ejectLocal();

            for (int i = 0; i < 4; i++)
            {
                input[i] = null;
            }

            // first, propagate the non-head flits along their worm paths
            // (no truncation, so this is very simple)
            for (int dir = 0; dir < 4; dir++)
            {
                if (linkIn[dir] != null && linkIn[dir].Out != null &&
                    !linkIn[dir].Out.isHeadFlit)
                {
#if DEBUG
                    Console.WriteLine("non-head flit: {0}", linkIn[dir].Out);
#endif
                    Flit f = linkIn[dir].Out; // grab the input flit from the link
                    linkIn[dir].Out = null;

                    if (wormRouting[dir] == -1)
                    {
                        // AGH: worm not routed
                        throw new Exception("SHOULDN'T HAPPEN!");
                    }

                    if (wormRouting[dir] != -2) // if not dropping, propagate the flit
                    {
                        linkOut[wormRouting[dir]].In = f;
                    }
                    if (f.isTailFlit) // if last flit, close the wormhole
                    {
                        wormRouting[dir] = -1;
                    }
                }
            }
            if (m_injectSlot != null && !m_injectSlot.isHeadFlit)
            {
                linkOut[wormRouting[4]].In = m_injectSlot;
                if (m_injectSlot.isTailFlit)
                {
                    wormRouting[4] = -1;
                }
                m_injectSlot = null;
            }

            // grab inputs into a local array
            int c = 0;
            for (int dir = 0; dir < 4; dir++)
            {
                if (linkIn[dir] != null && linkIn[dir].Out != null)
                {
                    linkIn[dir].Out.inDir = dir; // record this for below
                    input[c++]            = linkIn[dir].Out;
                    linkIn[dir].Out       = null;
                }
            }

            // step 1: get possible-output vectors for each input
            bool[,] possible = new bool[4, 4]; // (input,direction)
            int[] possible_count = new int[4];
            for (int i = 0; i < 4 && input[i] != null; i++)
            {
                PreferredDirection pd = determineDirection(input[i].dest);

                if (pd.xDir != Simulator.DIR_NONE &&
                    linkOut[pd.xDir].In == null)
                {
                    if (nackAvailable(pd.xDir))
                    {
                        possible[i, pd.xDir] = true;
                    }
                    else
                    {
                        Simulator.stats.nack_unavail.Add();
                        Simulator.stats.nack_unavail_by_src[ID].Add();
                    }
                }
                if (pd.yDir != Simulator.DIR_NONE &&
                    linkOut[pd.yDir].In == null)
                {
                    if (nackAvailable(pd.yDir))
                    {
                        possible[i, pd.yDir] = true;
                    }
                    else
                    {
                        Simulator.stats.nack_unavail.Add();
                        Simulator.stats.nack_unavail_by_src[ID].Add();
                    }
                }
            }
            // step 2: count possible requests per output
            for (int i = 0; i < 4; i++)
            {
                for (int dir = 0; dir < 4; dir++)
                {
                    if (possible[i, dir])
                    {
                        possible_count[dir]++;
                    }
                }
            }

            // step 3: if more than one possible for a given request, pick one with least
            //         requests; if tie, break randomly
            for (int i = 0; i < 4; i++)
            {
                int min_req = 10, min_req_j = -1;
                for (int j = 0; j < 4; j++)
                {
                    if (possible[i, j])
                    {
                        if (possible_count[j] < min_req)
                        {
                            min_req_j = j;
                            min_req   = possible_count[j];
                        }
                    }
                }

                for (int j = 0; j < 4; j++)
                {
                    possible[i, j] = false;
                }
                if (min_req_j != -1)
                {
                    possible[i, min_req_j] = true;
                }
            }
            // step 4,5: compute maximum priority requesting each output; set everyone
            // below this prio to false
            for (int dir = 0; dir < 4; dir++)
            {
                int max_prio = -1;
                for (int i = 0; i < 4; i++)
                {
                    if (possible[i, dir])
                    {
                        if (input[i].packet.scarab_retransmit_count > max_prio)
                        {
                            max_prio = input[i].packet.scarab_retransmit_count;
                        }
                    }
                }

                for (int i = 0; i < 4; i++)
                {
                    if (possible[i, dir] && input[i].packet.scarab_retransmit_count < max_prio)
                    {
                        possible[i, dir] = false;
                    }
                }
            }

            // step 6: select a winner in round-robin fashion
            int   offset      = getRR();
            int[] assignments = new int[4];
            for (int i = 0; i < 4; i++)
            {
                assignments[i] = -1;
            }
            for (int i_ = 0; i_ < 4; i_++)
            {
                int i = (i_ + offset) % 4;

                for (int dir = 0; dir < 4; dir++)
                {
                    if (possible[i, dir])
                    {
                        assignments[i] = dir;
                        for (int j = 0; j < 4; j++)
                        {
                            possible[j, dir] = false;
                        }
                    }
                }
            }

            //Flit oppBufferable = null;

            // assign outputs, choose a flit to opp. buffer if appropriate
            for (int i = 0; i < 4 && input[i] != null; i++)
            {
                int dir = assignments[i];
                if (dir == -1)
                {
                    // drop!
                    sendNack(input[i]);
                    wormRouting[input[i].inDir] = -2;

                    Simulator.stats.drop.Add();
                    Simulator.stats.drop_by_src[ID].Add();
                }
                else
                {
                    double decay = 0.875; //TODO parameterize
                    avgOutPriority[dir] = avgOutPriority[dir] * (1 - decay) + input[i].packet.scarab_retransmit_count * decay;

                    /*
                     * if (Config.opp_buffering
                     *  && !ejectedThisCycle
                     *  && input[i].packet.nrOfFlits == 1
                     *  && myProcessor.msh.hasOppBufferSpace()
                     *  && input[i].packet.scarab_retransmit_count < avgOutPriority[dir]
                     *  )
                     * {
                     *  // buffer opportunistically! (choose highest priority packet)
                     *  if (oppBufferable == null || input[i].packet.scarab_retransmit_count > oppBufferable.packet.scarab_retransmit_count)
                     *      oppBufferable = input[i];
                     * }
                     */
                }
            }

            for (int i = 0; i < 4 && input[i] != null; i++)
            {
                int dir = assignments[i];
                if (dir == -1)
                {
                    continue;
                }

                int   nackWire;
                ulong due = Simulator.CurrentRound + 4 * (1 + Simulator.distance(coord, input[i].dest));
                //nack_due[input[i].packet] = due;

                /*
                 * if (input[i] == oppBufferable)
                 * {
                 *  Console.WriteLine("Opp Buffering flit!");
                 *  sendTeardown(oppBufferable);
                 *  myProcessor.ejectFlit(oppBufferable);
                 *
                 *  nackWire = allocateNack(dir, -2, due);
                 * }
                 * else
                 */
                nackWire = allocateNack(dir, nackNr(input[i].inDir, input[i].nackWire), due);

                if (nackWire == -1)
                {
                    throw new Exception("shouldn't happen");
                }

                input[i].nackWire           = nackWire;
                linkOut[dir].In             = input[i];
                wormRouting[input[i].inDir] = dir;
            }

            // now try to inject
            if (m_injectSlot != null)
            {
                PreferredDirection pd = determineDirection(m_injectSlot.dest);
                ulong due             = Simulator.CurrentRound + 4 * (1 + Simulator.distance(coord, m_injectSlot.dest));
                //nack_due[m_injectSlot.packet] = due;

                if (pd.xDir != Simulator.DIR_NONE && linkOut[pd.xDir].In == null)
                {
                    int nackWire = allocateNack(pd.xDir, -2, due);
                    if (nackWire != -1)
                    {
                        linkOut[pd.xDir].In   = m_injectSlot;
                        m_injectSlot.nackWire = nackWire;
                        m_injectSlot          = null;
                        wormRouting[4]        = pd.xDir;
                    }
                }
                if (m_injectSlot != null && // check this again: only try y if x didn't work
                    pd.yDir != Simulator.DIR_NONE && linkOut[pd.yDir].In == null)
                {
                    int nackWire = allocateNack(pd.yDir, -2, due);
                    if (nackWire != -1)
                    {
                        linkOut[pd.yDir].In   = m_injectSlot;
                        m_injectSlot.nackWire = nackWire;
                        m_injectSlot          = null;
                        wormRouting[4]        = pd.yDir;
                    }
                }
            }
        }