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)
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:
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)))