headroom * Pt + headroom_i * It) MAX_THERMAL_FREQ_INDICES[cluster] = min( len(avail_freqs[cluster]) - 1, MAX_THERMAL_FREQ_INDICES[cluster]) headroom_i += headroom else: MAX_THERMAL_FREQ_INDICES[cluster] = len( avail_freqs[cluster]) - 1 if max(cpu_loads[cluster:(cluster + CLUSTER_SIZE)]) > CLUSTER_UP_THRESH: # increase the cluster frequency to max sel_cluster_freq[cluster] = MAX_THERMAL_FREQ_INDICES[cluster] #print("Tripped load limit. ({} > {})".format(max(cpu_loads[cluster:(cluster+CLUSTER_SIZE)]), CLUSTER_UP_THRESH)) 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_THERMAL_FREQ_INDICES[cluster]: sel_cluster_freq[cluster] = MAX_THERMAL_FREQ_INDICES[ cluster] break
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)))
while True and samples_taken < MAX_SAMPLES: samples_taken += 1 last_time = time.time()#time_stamp temps = cpu_usage.getTemps() # Set temperatures for the small, big, gpu and memory. Convert to kelvin T = [0.0]*4 T[0] = sum(temps)/len(temps)+ 273.15 T[1] = max(temps[0:4]) + 273.15 T[2] = temps[4] + 273.15 T[3] = max(temps[0:4]) + 273.15 # -1 indicates get loads for all cpus # 0.05 indicates s interval for measurement usages = cpu_usage.getCpuLoad(-1, 0.0) F = [0, 0, 0, 0] # Get frequency of small cluster, big cluster, GPU, and mem (convert from Khz to hz, except for GPU freq which is already reported by sysfs in hz) F[0] = float(cpu_usage.getClusterFreq(0))*1000 F[1] = float(cpu_usage.getClusterFreq(4))*1000 F[2] = float(cpu_usage.getGPUFreq()) F[3] = float(cpu_usage.getMemFreq())*1000 # Get voltages for each resource (function returns volts so no conversion necessary): V = [0.0, 0.0, 0.0, 0.0] V[0] = cpu_usage.resVoltage(0) V[1] = cpu_usage.resVoltage(4) V[2] = cpu_usage.GPUVoltage() V[3] = cpu_usage.memVoltage() if connected: total_power = getTelnetPower(SP2_tel, total_power) # Now compute the leakage power of each resource Pl = [0.0, 0.0, 0.0, 0.0] #eprint("Volts: {}".format(V))
try: ser = serial.Serial( port="/dev/ttySAC2",\ baudrate=115200,\ parity=serial.PARITY_NONE,\ stopbits=serial.STOPBITS_ONE,\ bytesize=serial.EIGHTBITS,\ timeout=0) print("Connected to: " + ser.portstr) connected = True except: print("Can't connect to serial. Skipping.") connected = False while True: temps = cpu_usage.getTemps() #print(temps) # -1 indicates get loads for all cpus # 0.05 indicates s interval for measurement usages = cpu_usage.getCpuLoad(-1, 0.1) #print(usages) line = '' for u in usages: line += ' ' + str(u) for t in temps: line += ' ' + str(t) line += ' ' + str(cpu_usage.getClusterFreq(0)) line += ' ' + str(cpu_usage.getClusterFreq(4)) ser.write(line) ser.write('\n\r') time.sleep(DELAY)