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 } }
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 }