public override void setThrottling()
        {
#if DEBUG_NETUTIL
            Console.Write("\n:: cycle {0} ::",
                          Simulator.CurrentRound);
#endif
            //get the MPKI value
            for (int i = 0; i < Config.N; i++)
            {
                prev_MPKI[i] = MPKI[i];
                if (num_ins_last_epoch[i] == 0)
                {
                    MPKI[i] = ((double)(L1misses[i] * 1000)) / (Simulator.stats.insns_persrc[i].Count);
                }
                else
                {
                    if (Simulator.stats.insns_persrc[i].Count - num_ins_last_epoch[i] > 0)
                    {
                        MPKI[i] = ((double)(L1misses[i] * 1000)) / (Simulator.stats.insns_persrc[i].Count - num_ins_last_epoch[i]);
                    }
                    else if (Simulator.stats.insns_persrc[i].Count - num_ins_last_epoch[i] == 0)
                    {
                        MPKI[i] = 0;
                    }
                    else
                    {
                        throw new Exception("MPKI error!");
                    }
                }
            }
            recordStats();

            if (isThrottling)
            {
                double netutil = ((double)(Simulator.stats.netutil.Total - lastNetUtil) / (double)Config.throttle_sampling_period);
#if DEBUG_NETUTIL
                Console.WriteLine("In throttle mode: avg netUtil = {0} thres at {1}",
                                  netutil, Config.netutil_throttling_threshold);
#endif

                /* TODO:
                 * 1.If the netutil remains high, lower the threshold value for each cluster
                 * to reduce the netutil further more and create a new pool/schedule for
                 * all the clusters. How to raise it back?
                 * Worst case: 1 app per cluster.
                 *
                 * 2.Find the difference b/w the current netutil and the threshold.
                 * Then increase the throttle rate for each cluster based on that difference.
                 *
                 * 3.maybe add stalling clusters?
                 * */
                isThrottling = false;
                //un-throttle the network
                for (int i = 0; i < Config.N; i++)
                {
                    setThrottleRate(i, false);
                }
                cluster_pool.removeAllClusters();
                double diff = netutil - Config.netutil_throttling_threshold;

                //Option1: adjust the mpki thresh for each cluster
                //if netutil within range of 10% increase MPKI boundary for each cluster
                if (Config.adaptive_cluster_mpki)
                {
                    double new_MPKI_thresh = cluster_pool.clusterThreshold();
                    if (diff < 0.10)
                    {
                        new_MPKI_thresh += 10;
                    }
                    else if (diff > 0.2)
                    {
                        new_MPKI_thresh -= 20;
                    }
                    cluster_pool.changeThresh(new_MPKI_thresh);
                }
                //Option2: adjust the throttle rate
                //
                //
                //Use alpha*total_MPKI+base to find the optimal netutil for performance
                //0.5 is the baseline netutil threshold
                //0.03 is calculated empricically using some base cases to find this number b/w total_mpki and target netutil
                double total_mpki = 0.0;
                for (int i = 0; i < Config.N; i++)
                {
                    total_mpki += MPKI[i];
                }

                double target_netutil = (0.03 * total_mpki + 50) / 100;
                //50% baseline
                if (Config.alpha)
                {
                    //within 2% range
                    if (netutil < (0.98 * target_netutil))
                    {
                        Config.RR_throttle_rate -= 0.02;
                    }
                    else if (netutil > (1.02 * target_netutil))
                    {
                        if (Config.RR_throttle_rate < 0.95)//max is 95%
                        {
                            Config.RR_throttle_rate += 0.01;
                        }
                    }

                    //if target is too high, only throttle max to 95% inj rate
                    if (target_netutil > 0.9)
                    {
                        Config.RR_throttle_rate = 0.95;
                    }
                }
                //Trying to force 60-70% netutil
                if (Config.adaptive_rate)
                {
                    if (diff < 0.1)
                    {
                        Config.RR_throttle_rate -= 0.02;
                    }
                    else if (diff > 0.2)
                    {
                        if (Config.RR_throttle_rate < 0.95)
                        {
                            Config.RR_throttle_rate += 0.01;
                        }
                    }
                }
#if DEBUG_CLUSTER_RATE
                Console.WriteLine("Netutil diff: {2}-{3}={1} New th rate:{0} New MPKI thresh: {6} Target netutil:{4} Total MPKI:{5}",
                                  Config.RR_throttle_rate, diff,
                                  netutil, Config.netutil_throttling_threshold, target_netutil, total_mpki, cluster_pool.clusterThreshold());
#endif
                Simulator.stats.total_th_rate.Add(Config.RR_throttle_rate);
            }


            if (thresholdTrigger()) // an abstract fn() that trigger whether to start throttling or not
            {
                //determine if the node is high intensive by using MPKI
                int    total_high = 0;
                double total_mpki = 0.0;
                for (int i = 0; i < Config.N; i++)
                {
                    total_mpki += MPKI[i];
                    if (MPKI[i] > Config.MPKI_high_node)
                    {
                        cluster_pool.addNewNode(i, MPKI[i]);
                        total_high++;
                        //TODO: add stats?
#if DEBUG
                        Console.Write("#ON#:Node {0} with MPKI {1} ", i, MPKI[i]);
#endif
                    }
                    else
                    {
#if DEBUG
                        Console.Write("@OFF@:Node {0} with MPKI {1} ", i, MPKI[i]);
#endif
                    }
                }
                Simulator.stats.total_sum_mpki.Add(total_mpki);
#if DEBUG
                Console.WriteLine(")");
#endif
                //if no node needs to be throttled, set throttling to false
                isThrottling = (total_high > 0)?true:false;
#if DEBUG_CLUSTER
                cluster_pool.printClusterPool();
#endif
            }
        }
Exemple #2
0
        public override void setThrottling()
        {
#if DEBUG_NETUTIL
            Console.Write("\n:: cycle {0} ::",
                          Simulator.CurrentRound);
            Console.WriteLine("cycle {0} @", Simulator.CurrentRound);
            Console.WriteLine("Netutil {0}", Simulator.network._cycle_netutil);
#endif

            double systemIPC    = 0.0;
            ulong  insnsRetired = 0;
            double sumMPKC      = 0.0;
            double sumMPKI      = 0.0;

            // get the MPKI value
            for (int i = 0; i < Config.N; i++)
            {
                insnsRetired = Simulator.stats.every_insns_persrc[i].Count - num_ins_last_epoch[i];;
                if (insnsRetired < 0)
                {
                    throw new Exception("Error gathering instructions!");
                }

                prev_MPKI[i] = MPKI[i];
                MPKI[i]      = (insnsRetired == 0) ? 0 : ((double)(L1misses[i] * 1000)) / insnsRetired;
                systemIPC   += ((double)insnsRetired) / Config.throttle_sampling_period;
                MPKC[i]      = (double)(L1misses[i] * 1000) / Config.throttle_sampling_period;
#if DEBUG_NETUTIL
                Console.WriteLine("MPKI: {0} MPKC: {1}", MPKI[i], MPKC[i]);
#endif
                sumMPKC += MPKC[i];
                sumMPKI += MPKI[i];
            }

            if (Config.bUseMPKC)
            {
                MPKC    = MPKI;
                sumMPKI = sumMPKC;
            }

            recordStats();
#if DEBUG_NETUTIL
            Console.WriteLine("Sum MPKI {0} MPKC {1} Avg MPKC {2}", sumMPKI, sumMPKC, sumMPKC / Config.N);
#endif

            ACTRateAdjust(systemIPC);

#if DEBUG_NETUTIL
            Console.WriteLine("*****Adjusted throttle rate: {0}", Config.RR_throttle_rate);
#endif
            // Clear the cluster formatoin from the last epoch
            cluster_pool.removeAllClusters();
            throttled_cluster.removeAllNodes();
            low_intensity_cluster.removeAllNodes();

            List <int> sortedList    = new List <int>();
            double     total_mpki    = 0.0;
            double     small_mpki    = 0.0;
            double     current_allow = 0.0;
            int        total_high    = 0;

            for (int i = 0; i < Config.N; i++)
            {
                sortedList.Add(i);
                total_mpki += MPKI[i];
                //stats recording-see what's the total mpki composed by low/med apps
                if (MPKI[i] <= 30)
                {
                    small_mpki += MPKI[i];
                }
            }

            //sort by mpki
            if (Config.act_reverse_sort)
            {
                sortedList.Sort(ReverseCompareByMpki);
            }
            else
            {
                sortedList.Sort(CompareByMpki);
            }

            //foreach (int sortListIdx in sortedList)
            //    Console.WriteLine("Idx: {0} MPKI: {1}", sortListIdx, MPKI[sortListIdx]);

#if DEBUG_CLUSTER
            for (int i = 0; i < Config.N; i++)
            {
                writeNode(sortedList[i]);
                Console.WriteLine("-->MPKI:{0}", MPKI[sortedList[i]]);
            }
            Console.WriteLine("*****total MPKI: {0}", total_mpki);
            Console.WriteLine("*****total MPKIs of apps with MPKI<30: {0}\n", small_mpki);
#endif
            //find the first few apps that will be allowed to run freely without being throttled
            for (int list_index = 0; list_index < Config.N; list_index++)
            {
                int node_id = sortedList[list_index];
#if DEBUG_CLUSTER
                writeNode(node_id);
#endif

                /*
                 * Low intensity cluster conditions:
                 * 1. filling enabled, then fill the low cluster up til free_total_mpki.
                 * 2. if filling not enabled, then apps with mpki lower than 'low_apps_mpki_thresh' will be put into the cluster.
                 * */

                // Need to do this for the GPU
                if (((Config.free_total_MPKI > 0 && (current_allow + MPKI[node_id] <= Config.free_total_MPKI) && Config.low_cluster_filling_enabled) ||
                     (!Config.low_cluster_filling_enabled && MPKI[node_id] <= Config.low_apps_mpki_thresh)) && (node_id != Config.gpuLoc))
                {
#if DEBUG_CLUSTER
                    Console.WriteLine("->Low node: {0}", node_id);
#endif
                    low_intensity_cluster.addNode(node_id, MPKI[node_id]);
                    current_allow += MPKI[node_id];
                    Simulator.stats.low_cluster[node_id].Add();
                    continue;
                }
                else if (node_id == Config.gpuLoc || (MPKI[node_id] >= Config.cluster_MPKI_threshold && Config.always_cluster_enabled))
                {
                    //If an application doesn't fit into one cluster, it will always be throttled
#if DEBUG_CLUSTER
                    Console.WriteLine("->Alway throttled node: {0}", node_id);
#endif
                    throttled_cluster.addNode(node_id, MPKI[node_id]);
                    Simulator.stats.high_cluster[node_id].Add();
                    total_high++;
                }
                else
                {
#if DEBUG_CLUSTER
                    Console.WriteLine("->RR node: {0}", node_id);
#endif
                    cluster_pool.addNewNode(node_id, MPKI[node_id]);
                    Simulator.stats.rr_cluster[node_id].Add();
                    total_high++;
                }
            }

            //randomly start a cluster to begin with instead of always the first one
            cluster_pool.randClusterId();
#if DEBUG_CLUSTER
            Console.WriteLine("total high: {0}", total_high);
            Console.WriteLine("-->low cluster mpki: {0}", current_allow);
#endif
            //STATS
            Simulator.stats.allowed_sum_mpki.Add(current_allow);
            Simulator.stats.total_sum_mpki.Add(total_mpki);

            sortedList.Clear();
#if DEBUG_CLUSTER
            cluster_pool.printClusterPool();
#endif
        }