cpu_graph.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/bin/env python3
  2. #
  3. import sys
  4. import json
  5. import gzip
  6. import numpy as np
  7. import matplotlib.pylab as plt
  8. #
  9. def load_cpu_stats(path):
  10. with gzip.GzipFile(path, 'r') as f:
  11. return json.load(f)
  12. #
  13. #
  14. def calculate_cpu_usage(initial, current):
  15. """
  16. Calculation adapted from: https://stackoverflow.com/questions/23367857/accurate-calculation-of-cpu-usage-given-in-percentage-in-linux/
  17. """
  18. #
  19. initial_idle = initial['idle'] + initial['iowait']
  20. current_idle = current['idle'] + current['iowait']
  21. #
  22. initial_non_idle = initial['user'] + initial['nice'] + initial['system'] + initial['irq'] + initial['softirq'] + initial['steal']
  23. current_non_idle = current['user'] + current['nice'] + current['system'] + current['irq'] + current['softirq'] + current['steal']
  24. #
  25. initial_total = initial_idle + initial_non_idle
  26. current_total = current_idle + current_non_idle
  27. #
  28. return (current_non_idle-initial_non_idle)/(current_total-initial_total)
  29. #
  30. def calculate_cpu_usage_continuous(stats):
  31. cpu_usages = []
  32. for i in range(len(stats)-1):
  33. cpu_usages.append(calculate_cpu_usage(stats[i], stats[i+1]))
  34. #
  35. return cpu_usages
  36. #
  37. def parse_range_list(range_list_str):
  38. '''
  39. Take an input like '1-3,5,7-10' and return a list like [1,2,3,5,7,8,9,10].
  40. '''
  41. #
  42. range_strings = range_list_str.split(',')
  43. all_items = []
  44. for range_str in range_strings:
  45. if '-' in range_str:
  46. # in the form '12-34'
  47. range_ends = [int(x) for x in range_str.split('-')]
  48. assert(len(range_ends) == 2)
  49. all_items.extend(range(range_ends[0], range_ends[1]+1))
  50. else:
  51. # just a number
  52. all_items.append(int(range_str))
  53. #
  54. #
  55. return all_items
  56. #
  57. cpu_data = load_cpu_stats(sys.argv[1])
  58. #
  59. unused_cpus = [str(x) for x in parse_range_list('128-129,138-139,18-19,148-149,28-29,158-159,38-39,48-49,58-59,68-69,78-79,98-99,108-109,118-119')]
  60. numa_sets = [[0, 80, 1, 81], [10, 90, 11, 91], [20, 100, 21, 101], [30, 110, 31, 111], [40, 120, 41, 121], [50, 130, 51, 131], [60, 140, 61, 141], [70, 150, 71, 151], [2, 82, 3, 83], [12, 92, 13, 93], [22, 102, 23, 103], [32, 112, 33, 113], [42, 122, 43, 123], [52, 132, 53, 133], [62, 142, 63, 143], [72, 152, 73, 153], [4, 84, 5, 85], [14, 94, 15, 95], [24, 104, 25, 105], [34, 114, 35, 115], [44, 124, 45, 125], [54, 134, 55, 135], [64, 144, 65, 145], [74, 154, 75, 155], [6, 86, 7, 87], [16, 96, 17, 97], [26, 106, 27, 107], [36, 116, 37, 117], [46, 126, 47, 127], [56, 136, 57, 137], [66, 146, 67, 147], [76, 156, 77, 157], [8, 88, 9, 89]]
  61. #
  62. timestamps = (np.array(cpu_data['timestamps'][1:]) + np.array(cpu_data['timestamps'][:-1])) / 2
  63. cpu_usages = {int(cpu): np.array(calculate_cpu_usage_continuous(cpu_data['stats']['cpus'][cpu])) for cpu in cpu_data['stats']['cpus'] if cpu not in unused_cpus}
  64. tor_usages = [np.sum([cpu_usages[cpu] for cpu in x], axis=0)/4 for x in numa_sets]
  65. print(len(cpu_usages))
  66. print(len(tor_usages))
  67. #
  68. plt.figure()
  69. #
  70. for cpu in tor_usages:
  71. plt.plot(timestamps, cpu*100)
  72. #
  73. plt.xlabel('Time (s)')
  74. plt.ylabel('CPU Usage (Average over 4 cores)')
  75. plt.show()