Throttle.hh revision 7454
16019SN/A/*
26019SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
37102SN/A * All rights reserved.
47102SN/A *
57102SN/A * Redistribution and use in source and binary forms, with or without
67102SN/A * modification, are permitted provided that the following conditions are
77102SN/A * met: redistributions of source code must retain the above copyright
87102SN/A * notice, this list of conditions and the following disclaimer;
97102SN/A * redistributions in binary form must reproduce the above copyright
107102SN/A * notice, this list of conditions and the following disclaimer in the
117102SN/A * documentation and/or other materials provided with the distribution;
127102SN/A * neither the name of the copyright holders nor the names of its
137102SN/A * contributors may be used to endorse or promote products derived from
147102SN/A * this software without specific prior written permission.
156019SN/A *
166019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019SN/A */
286019SN/A
296019SN/A/*
306019SN/A * The class to implement bandwidth and latency throttle. An instance
316019SN/A * of consumer class that can be woke up. It is only used to control
326019SN/A * bandwidth at output port of a switch. And the throttle is added
336019SN/A * *after* the output port, means the message is put in the output
346019SN/A * port of the PerfectSwitch (a intermediateBuffers) first, then go
356019SN/A * through the Throttle.
366019SN/A */
376019SN/A
386019SN/A#ifndef __MEM_RUBY_NETWORK_SIMPLE_THROTTLE_HH__
396019SN/A#define __MEM_RUBY_NETWORK_SIMPLE_THROTTLE_HH__
406019SN/A
416019SN/A#include <iostream>
426019SN/A#include <vector>
436019SN/A
446019SN/A#include "mem/ruby/common/Consumer.hh"
456019SN/A#include "mem/ruby/common/Global.hh"
466019SN/A#include "mem/ruby/network/Network.hh"
476019SN/A#include "mem/ruby/system/NodeID.hh"
486019SN/A#include "mem/ruby/system/System.hh"
496019SN/A
506019SN/Aclass MessageBuffer;
516019SN/A
526310SN/Aclass Throttle : public Consumer
537191Sgblack@eecs.umich.edu{
547191Sgblack@eecs.umich.edu  public:
557191Sgblack@eecs.umich.edu    Throttle(int sID, NodeID node, int link_latency,
566268SN/A        int link_bandwidth_multiplier);
576268SN/A    Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier);
586268SN/A    ~Throttle() {}
596268SN/A
607161Sgblack@eecs.umich.edu    void addLinks(const std::vector<MessageBuffer*>& in_vec,
617206Sgblack@eecs.umich.edu        const std::vector<MessageBuffer*>& out_vec);
626019SN/A    void wakeup();
637129Sgblack@eecs.umich.edu
646019SN/A    void printStats(std::ostream& out) const;
656268SN/A    void clearStats();
667139Sgblack@eecs.umich.edu    void printConfig(std::ostream& out) const;
677161Sgblack@eecs.umich.edu    // The average utilization (a percent) since last clearStats()
687161Sgblack@eecs.umich.edu    double getUtilization() const;
697203Sgblack@eecs.umich.edu    int
707252Sgblack@eecs.umich.edu    getLinkBandwidth() const
717161Sgblack@eecs.umich.edu    {
727161Sgblack@eecs.umich.edu        return RubySystem::getNetwork()->getEndpointBandwidth() *
737161Sgblack@eecs.umich.edu            m_link_bandwidth_multiplier;
747161Sgblack@eecs.umich.edu    }
757161Sgblack@eecs.umich.edu    int getLatency() const { return m_link_latency; }
767161Sgblack@eecs.umich.edu
777195Sgblack@eecs.umich.edu    const std::vector<std::vector<int> >&
786268SN/A    getCounters() const
797161Sgblack@eecs.umich.edu    {
806268SN/A        return m_message_counters;
816268SN/A    }
826268SN/A
836268SN/A    void clear();
847139Sgblack@eecs.umich.edu
856268SN/A    void print(std::ostream& out) const;
866268SN/A
876741SN/A  private:
886756SN/A    void init(NodeID node, int link_latency, int link_bandwidth_multiplier);
896756SN/A    void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
906756SN/A    void linkUtilized(double ratio) { m_links_utilized += ratio; }
916756SN/A
926756SN/A    // Private copy constructor and assignment operator
936756SN/A    Throttle(const Throttle& obj);
946756SN/A    Throttle& operator=(const Throttle& obj);
956756SN/A
966756SN/A    std::vector<MessageBuffer*> m_in;
976756SN/A    std::vector<MessageBuffer*> m_out;
986756SN/A    std::vector<std::vector<int> > m_message_counters;
996756SN/A    int m_vnets;
1006756SN/A    std::vector<int> m_units_remaining;
1016756SN/A    int m_sID;
1026756SN/A    NodeID m_node;
1036756SN/A    int m_link_bandwidth_multiplier;
1046756SN/A    int m_link_latency;
1056756SN/A    int m_wakeups_wo_switch;
1067102SN/A
1076741SN/A    // For tracking utilization
1086019SN/A    Time m_ruby_start;
1096268SN/A    double m_links_utilized;
1107120Sgblack@eecs.umich.edu};
1116268SN/A
1127120Sgblack@eecs.umich.eduinline std::ostream&
1137161Sgblack@eecs.umich.eduoperator<<(std::ostream& out, const Throttle& obj)
1147194Sgblack@eecs.umich.edu{
1157210Sgblack@eecs.umich.edu    obj.print(out);
1167161Sgblack@eecs.umich.edu    out << std::flush;
1177255Sgblack@eecs.umich.edu    return out;
1186269SN/A}
1196268SN/A
1207134Sgblack@eecs.umich.edu#endif // __MEM_RUBY_NETWORK_SIMPLE_THROTTLE_HH__
1216268SN/A