public void addNewNodeUniform(int id, double mpki)
        {
            nodes_pool.Add(id);
            q.Add(new Cluster());
            Cluster cur_cluster = q[q.Count - 1];

            cur_cluster.addNode(id, mpki);
            return;
        }
        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.every_insns_persrc[i].Count);
                }
                else
                {
                    if (Simulator.stats.every_insns_persrc[i].Count - num_ins_last_epoch[i] > 0)
                    {
                        MPKI[i] = ((double)(L1misses[i] * 1000)) / (Simulator.stats.every_insns_persrc[i].Count - num_ins_last_epoch[i]);
                    }
                    else if (Simulator.stats.every_insns_persrc[i].Count - num_ins_last_epoch[i] == 0)
                    {
                        MPKI[i] = 0;
                    }
                    else
                    {
                        throw new Exception("MPKI error!");
                    }
                }
            }
            recordStats();

            double netutil = ((double)(Simulator.stats.netutil.Total - lastNetUtil) / (double)Config.throttle_sampling_period);
#if DEBUG_NETUTIL
            Console.WriteLine("\n*****avg netUtil = {0} TARGET at {1}",
                              netutil, Config.netutil_throttling_target);
#endif

            /*
             * 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?
             * */
            //un-throttle the network
            for (int i = 0; i < Config.N; i++)
            {
                setThrottleRate(i, false);
            }
            //Clear all the clusters

/*#if DEBUG_CLUSTER
 *          Console.WriteLine("cycle {0} ___Clear clusters___",Simulator.CurrentRound);
 #endif
 *          cluster_pool.removeAllClusters();
 *          throttled_cluster.removeAllNodes();
 *          low_intensity_cluster.removeAllNodes();*/

            double th_rate     = Config.RR_throttle_rate;
            double adjust_rate = 0;
            if (th_rate >= 0 && th_rate < 0.7)
            {
                adjust_rate = 0.1;//10%
            }
            else if (th_rate < 0.90)
            {
                adjust_rate = 0.02;//2%
            }
            else
            {
                adjust_rate = 0.01;//1%
            }
            if (netutil < Config.netutil_throttling_target)
            {
                if ((th_rate - adjust_rate) >= 0)
                {
                    Config.RR_throttle_rate -= adjust_rate;
                }
                else
                {
                    Config.RR_throttle_rate = 0;
                }
            }
            else
            {
                if ((th_rate + adjust_rate) <= Config.max_throttle_rate)
                {
                    Config.RR_throttle_rate += adjust_rate;
                }
                else
                {
                    Config.RR_throttle_rate = Config.max_throttle_rate;
                }
            }
            if (Config.RR_throttle_rate < 0 || Config.RR_throttle_rate > Config.max_throttle_rate)
            {
                throw new Exception("Throttle rate out of range (0 , max value)!!");
            }

#if DEBUG_NETUTIL
            Console.WriteLine("*****Adjusted throttle rate: {0}", Config.RR_throttle_rate);
#endif
            Simulator.stats.total_th_rate.Add(Config.RR_throttle_rate);


#if DEBUG_CLUSTER
            Console.WriteLine("cycle {0} ___Clear clusters___", Simulator.CurrentRound);
#endif
            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
            sortedList.Sort(CompareByMpki);
#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];
                writeNode(node_id);

                /*
                 * 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.
                 * */

                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))
                {
#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 (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("->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("->High 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
        }
Exemple #3
0
        public override void setThrottling()
        {
            //get the MPKI values
            for (int grp = 0; grp < wkld.GroupCount; grp++)
            {
                ulong insns = 0, misses = 0;
                for (int thd = 0; thd < wkld.getGroupSize(grp); thd++)
                {
                    int node = wkld.mapThd(grp, thd);
                    insns  += Simulator.stats.every_insns_persrc[node].Count - num_ins_last_epoch[node];
                    misses += L1misses[node];
                }
                if (insns == 0)
                {
                    MPKI[grp] = 0.0;
                }
                else
                {
                    MPKI[grp] = (double)misses / insns * 1000.0;
                }
            }

            recordStats();

            double netutil = ((double)(Simulator.stats.netutil.Total - lastNetUtil) / (double)Config.throttle_sampling_period);

            /*
             * 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?
             * */
            //un-throttle the network
            for (int i = 0; i < Config.N; i++)
            {
                setThrottleRate(i, false);
            }

            double th_rate     = Config.RR_throttle_rate;
            double adjust_rate = 0;

            if (th_rate >= 0 && th_rate < 0.7)
            {
                adjust_rate = 0.1;//10%
            }
            else if (th_rate < 0.90)
            {
                adjust_rate = 0.02;//2%
            }
            else
            {
                adjust_rate = 0.01;//1%
            }
            if (netutil < Config.netutil_throttling_target)
            {
                if ((th_rate - adjust_rate) >= 0)
                {
                    Config.RR_throttle_rate -= adjust_rate;
                }
                else
                {
                    Config.RR_throttle_rate = 0;
                }
            }
            else
            {
                if ((th_rate + adjust_rate) <= Config.max_throttle_rate)
                {
                    Config.RR_throttle_rate += adjust_rate;
                }
                else
                {
                    Config.RR_throttle_rate = Config.max_throttle_rate;
                }
            }
            if (Config.RR_throttle_rate < 0 || Config.RR_throttle_rate > Config.max_throttle_rate)
            {
                throw new Exception("Throttle rate out of range (0 , max value)!!");
            }

            Simulator.stats.total_th_rate.Add(Config.RR_throttle_rate);


            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 grp = 0; grp < wkld.GroupCount; grp++)
            {
                sortedList.Add(grp);
                total_mpki += MPKI[grp];
                //stats recording-see what's the total mpki composed by low/med apps
                if (MPKI[grp] <= 30)
                {
                    small_mpki += MPKI[grp];
                }
            }
            //sort by mpki
            sortedList.Sort(CompareByMpki);

            //find the first few apps that will be allowed to run freely without being throttled
            for (int grp = 0; grp < wkld.GroupCount; grp++)
            {
                /*
                 * 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.
                 * */

                if (((current_allow + MPKI[grp] <= Config.free_total_MPKI) && Config.low_cluster_filling_enabled) ||
                    (!Config.low_cluster_filling_enabled && MPKI[grp] <= Config.low_apps_mpki_thresh))
                {
                    low_intensity_cluster.addNode(grp, MPKI[grp]);
                    current_allow += MPKI[grp];

                    for (int thd = 0; thd < wkld.getGroupSize(grp); thd++)
                    {
                        Simulator.stats.low_cluster[wkld.mapThd(grp, thd)].Add();
                    }

                    continue;
                }
                else if (MPKI[grp] > Config.cluster_MPKI_threshold && Config.always_cluster_enabled)
                {
                    //If an application doesn't fit into one cluster, it will always be throttled
                    throttled_cluster.addNode(grp, MPKI[grp]);

                    for (int thd = 0; thd < wkld.getGroupSize(grp); thd++)
                    {
                        Simulator.stats.high_cluster[wkld.mapThd(grp, thd)].Add();
                    }

                    total_high++;
                }
                else
                {
                    cluster_pool.addNewNode(grp, MPKI[grp]);

                    for (int thd = 0; thd < wkld.getGroupSize(grp); thd++)
                    {
                        Simulator.stats.rr_cluster[wkld.mapThd(grp, thd)].Add();
                    }

                    total_high++;
                }
            }
            //randomly start a cluster to begin with instead of always the first one
            cluster_pool.randClusterId();
            //STATS
            Simulator.stats.allowed_sum_mpki.Add(current_allow);
            Simulator.stats.total_sum_mpki.Add(total_mpki);

            sortedList.Clear();
        }
        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);
                }
                //Clear all the clusters
#if DEBUG_CLUSTER
                Console.WriteLine("cycle {0} ___Clear clusters___", Simulator.CurrentRound);
#endif
                cluster_pool.removeAllClusters();
                throttled_cluster.removeAllNodes();
                low_intensity_cluster.removeAllNodes();

                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_NETUTIL
                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 DEBUG_CLUSTER
            Console.WriteLine("***SET THROTTLING Thresh trigger point*** CYCLE{0}", Simulator.CurrentRound);
#endif
            //TODO: test phase can also reduce the mpki,so...might not have consecutive test phases
            if (thresholdTrigger()) // an abstract fn() that trigger whether to start throttling or not
            {
#if DEBUG_CLUSTER
                Console.WriteLine("Congested!! Trigger throttling! isTest {0}, num th {1}, num samp {2}",
                                  isTestPhase, num_test_phases, num_throttle_periods);
#endif
#if DEBUG_CLUSTER
                Console.WriteLine("cycle {0} ___Clear clusters___", Simulator.CurrentRound);
#endif
                cluster_pool.removeAllClusters();
                throttled_cluster.removeAllNodes();
                low_intensity_cluster.removeAllNodes();

                ///////State Trasition
                //Initial state
                if (num_throttle_periods == 0 && num_test_phases == 0)
                {
                    isTestPhase = true;
                }
                //From test->cluster throttling
                if (isTestPhase && num_test_phases == Config.apps_test_freq)
                {
                    isTestPhase     = false;
                    num_test_phases = 0;
                }
                //From cluster throttling->test
                if (num_throttle_periods == Config.sampling_period_freq)
                {
                    //reset ipc_accum_diff
                    for (int node_id = 0; node_id < Config.N; node_id++)
                    {
                        ipc_accum_diff[node_id] = 0.0;
                    }
                    isTestPhase          = true;
                    num_throttle_periods = 0;
                }

                ///////Cluster Distribution
                if (isTestPhase == true)
                {
                    num_test_phases++;
                    //Add every node to high cluster
                    int    total_high = 0;
                    double total_mpki = 0.0;
                    for (int i = 0; i < Config.N; i++)
                    {
                        total_mpki += MPKI[i];
                        cluster_pool.addNewNodeUniform(i, MPKI[i]);
                        total_high++;
#if DEBUG
                        Console.Write("#ON#: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
                }
                else
                {
                    //Increment the number of throttle periods so that the test phase can kick back
                    //in after certain number of throttle periods.
                    num_throttle_periods++;
                    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
                    sortedList.Sort(CompareByMpki);
#if DEBUG_CLUSTER
                    for (int i = 0; i < Config.N; i++)
                    {
                        Console.WriteLine("ID:{0} MPKI:{1}", sortedList[i], 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];
                        //add the node that has no performance gain from free injection slot to
                        //always throttled cluster.
                        double ipc_avg_diff = ipc_accum_diff[node_id] / Config.apps_test_freq;
#if DEBUG_CLUSTER
                        Console.WriteLine("Node {0} with ipc diff {1}", node_id, ipc_avg_diff * 100);
#endif
                        //If an application doesn't fit into one cluster, it will always be throttled
                        if (ipc_avg_diff < Config.sensitivity_threshold || (Config.use_cluster_threshold && MPKI[node_id] > Config.cluster_MPKI_threshold))
                        {
#if DEBUG_CLUSTER
                            Console.WriteLine("->Throttled node: {0}", node_id);
#endif
                            throttled_cluster.addNode(node_id, MPKI[node_id]);
                        }
                        else
                        {
                            if (withInRange(current_allow + MPKI[node_id], Config.free_total_MPKI))
                            {
#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];
                                continue;
                            }
                            else
                            {
#if DEBUG_CLUSTER
                                Console.WriteLine("->High node: {0}", node_id);
#endif
                                cluster_pool.addNewNode(node_id, MPKI[node_id]);
                                total_high++;
                            }
                        }
                    }
#if DEBUG_CLUSTER
                    Console.WriteLine("total high: {0}\n", total_high);
#endif
                    //STATS
                    Simulator.stats.allowed_sum_mpki.Add(current_allow);
                    Simulator.stats.total_sum_mpki.Add(total_mpki);

                    sortedList.Clear();
                    isThrottling = (total_high > 0)?true:false;
#if DEBUG_CLUSTER
                    cluster_pool.printClusterPool();
#endif
                }
            }
        }
Exemple #5
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
        }
Exemple #6
0
        /**
         * @brief Add a new node to the cluster.
         *
         * If the new node doesn't exceed the total mpki of the most recent added cluster,
         * the node is inserted to that cluster. Otherwise, it's added to a new cluster.
         **/
        public override void addNewNode(int id, double mpki)
        {
            nodes_pool.Add(id);
            Cluster cur_cluster;

            if (q.Count == 0)
            {
                q.Add(new Cluster());
                cur_cluster = q[0];
                cur_cluster.addNode(id, mpki);
                return;
            }
            else
            {
                List <int> availCluster    = new List <int>();
                bool       needNewCluster  = true;
                double     maxDist         = 0;
                Cluster    selectedCluster = q[0];
                for (int i = 0; i < q.Count; i++)
                {
                    cur_cluster = q[i];
                    double sum_MPKI = cur_cluster.totalClusterMPKI() + mpki;
#if DEBUG_DIST
                    Console.WriteLine("sum_MPKI = {0}, mpki_threshold = {1}", sum_MPKI, _mpki_threshold);
#endif
                    if (sum_MPKI <= _mpki_threshold)
                    {
                        //cur_cluster.addNode(id,mpki);
                        availCluster.Add(i);
                        needNewCluster = false;
                        //return;
                    }
                }
                for (int i = 0; i < availCluster.Count; i++)
                {
                    double avgDist = 0.0;
                    cur_cluster = q[i];
                    int [] nodes = cur_cluster.allNodes();
                    for (int j = 0; j < nodes.Length; j++)
                    {
                        avgDist += computeDist(nodes[j], id);
                    }
                    avgDist = avgDist / nodes.Length;
                    if (avgDist > maxDist)
                    {
                        selectedCluster = cur_cluster;
                        maxDist         = avgDist;
                    }
                }
                if (needNewCluster)
                {
#if DEBUG_DIST
                    Console.WriteLine("Adding a new cluster");
#endif
                    q.Add(new Cluster());
                    //count is incremented
                    cur_cluster = q[q.Count - 1];
                    cur_cluster.addNode(id, mpki);
                    return;
                }
                else
                {
#if DEBUG_DIST
                    int [] allNodes = selectedCluster.allNodes();
                    Console.Write("Adding {0} to cluster with nodes: ", id);
                    for (int i = 0; i < allNodes.Length; i++)
                    {
                        Console.Write("{0} ", allNodes[i]);
                    }
                    Console.WriteLine("");
#endif
                    selectedCluster.addNode(id, mpki);
                }
            }
            return;
        }