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 }
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 } } }
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 }
/** * @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; }