예제 #1
0
	def __init__(self, clusters=[0,4]):
		self.clusters = clusters
		sysfs_utils.setUserSpace(clusters=clusters)
		self.avail_freqs = {x:list() for x in clusters}
		self.sel_cluster_freq = {x:0 for x in clusters}
		for cluster in clusters:
			self.avail_freqs[cluster] = sysfs_utils.getAvailFreqs(cluster)
예제 #2
0
         except:
             therm_index = -1
         if therm_index > -1:
             THERMAL_THRESH = float(sys.argv[therm_index + 1])
     except:
         usage()
 print(
     "Starting userspace ondemand with thermal limit of {} celsius on clusters {}."
     .format(THERMAL_THRESH, clusters))
 print("WARNING: thermal limits are only in effect for the big cluster.")
 atexit.register(sysfs_utils.unsetUserSpace, clusters=clusters)
 sysfs_utils.setUserSpace(clusters=clusters)
 avail_freqs = {x: list() for x in clusters}
 sel_cluster_freq = {x: 0 for x in clusters}
 for cluster in clusters:
     avail_freqs[cluster] = sysfs_utils.getAvailFreqs(cluster)
 Fs = {x: 0 for x in clusters}
 Fs_new = {x: 0 for x in clusters}
 U = {x: 0.0 for x in clusters}
 MAX_THERMAL_FREQ_INDICES = {x: 0 for x in clusters}
 headroom_i = 0
 while True:
     last_time = time.time()
     # Get the latest cpu usages
     cpu_loads = sysfs_utils.getCpuLoad(n=-1, interval=0.0)
     for cluster in clusters:
         if cluster == 4:
             # get the first four temp which correspond to the big cluster cores
             T = sysfs_utils.getTemps()[0:4]
             headroom = THERMAL_THRESH - max(T)
             if headroom <= 0:
예제 #3
0
def ondemand_power(clusters, POWER_THRESH):
    # Setup output and making sure system is in userspace gov
    SP2_tel = setup(clusters, POWER_THRESH)
    # Setup runtime vars:
    avail_freqs = {x: list() for x in clusters}
    sel_cluster_freq = {x: 0 for x in clusters}
    for cluster in clusters:
        avail_freqs[cluster] = sysfs_utils.getAvailFreqs(cluster)
    Fs = {x: 0 for x in clusters}
    Fs_new = {x: 0 for x in clusters}
    U = {x: 0.0 for x in clusters}
    total_power = 0
    MAX_FREQ_INDICES = {x: 0 for x in clusters}
    # Run the governor:
    while True:
        last_time = time.time()
        # Get the latest cpu usages
        cpu_loads = sysfs_utils.getCpuLoad(n=-1, interval=0.0)
        for cluster in clusters:
            # Code to handle power limits ********************************************************
            if cluster == 4:
                T = sysfs_utils.getTemps()[0:4]
                F = float(sysfs_utils.getClusterFreq(cluster)) / 1000000
                total_power = getTelnetPower(SP2_tel, total_power)
                leakage_power = leakagePower(c1, c2, Igate, big_f_to_v[F],
                                             max(T) + 273.15)
                dynamic_power = (total_power - peripheral_power -
                                 leakage_power)
                if logfile is not None:
                    logfile.write("{}\t{}\t{}\n".format(
                        total_power, leakage_power, dynamic_power))
                remaining_power = POWER_THRESH - (total_power -
                                                  peripheral_power)
                if remaining_power <= 0:
                    MAX_FREQ_INDICES[cluster] = max(
                        MAX_FREQ_INDICES[cluster] - 1, 0)
                    print("Tripped power limit. ({} > {})".format(
                        total_power - peripheral_power, POWER_THRESH))
                else:
                    MAX_FREQ_INDICES[cluster] += math.floor(remaining_power *
                                                            P)
                    MAX_FREQ_INDICES[cluster] = min(
                        len(avail_freqs[cluster]) - 1,
                        MAX_FREQ_INDICES[cluster])
            else:  # Else if the little cluster, just proceed as ondemand would normally
                MAX_FREQ_INDICES[cluster] = len(avail_freqs[cluster]) - 1
            # End code to handle power limits ****************************************************

            # In the case of either cluster, apply the ondemand algorithm, but with upper freq limit
            if max(cpu_loads[cluster:(cluster +
                                      CLUSTER_SIZE)]) > CLUSTER_UP_THRESH:
                # increase the cluster frequency to maximum allowed
                sel_cluster_freq[cluster] = MAX_FREQ_INDICES[cluster]
            else:
                # find a frequency that will maintain no more than LOAD_TARGET usage on any core.
                Fs[cluster] = sysfs_utils.getClusterFreq(cluster)
                Fs_new[cluster] = min( Fs[cluster], target_frequency(max(cpu_loads[cluster:(cluster+CLUSTER_SIZE)]),\
                         avail_freqs[cluster][0], avail_freqs[cluster][-1]) )
                # Search up to and including the current frequency for one that maintains the
                # desired load:
                for index, frequency in enumerate(avail_freqs[cluster]):
                    if frequency == Fs_new[cluster]:
                        sel_cluster_freq[cluster] = index
                        break
                    elif frequency > Fs_new[cluster]:
                        sel_cluster_freq[cluster] = max(index - 1, 0)
                        break
                    elif index >= MAX_FREQ_INDICES[cluster]:
                        sel_cluster_freq[cluster] = MAX_FREQ_INDICES[cluster]
                        break
            selected_index = int(sel_cluster_freq[cluster])
            try:
                sysfs_utils.setClusterFreq(cluster, \
                       avail_freqs[cluster][selected_index] )
            except:
                print(sys.exc_info()[0])
                print("ERROR: tried to access {} for cluster {}".format(
                    selected_index, cluster))
                print(avail_freqs[cluster])
        time.sleep(max(0, REFRESH_PERIOD - (time.time() - last_time)))