performance.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import pickle
  2. import numpy as np
  3. from timeit import default_timer as timer
  4. import matplotlib.pyplot as plt
  5. from acceleration import *
  6. import analysis.utils as utils
  7. timescale = 10 # ms, approximate time per attempt
  8. massive = True # whether all particles are massive
  9. functions = [bruteForce, bruteForceNumba, bruteForceNumbaOptimized, bruteForceCPP, barnesHutCPP]
  10. labels = ['Brute force', 'Brute force Numba', 'Brute force Numba opt.', 'Brute force [C++]', 'Barnes-Hut [C++]']
  11. styles = ['solid', 'dashed', 'solid', 'dashed', 'solid']
  12. colours = ['cornflowerblue', 'cornflowerblue', 'darkorange', 'darkorange', 'black']
  13. if not massive: #do not evaluate barnes hut
  14. functions, labels, styles, colours = functions[:-1], labels[:-1], styles[:-1], colours[:-1]
  15. timess = []
  16. for i in range(len(functions)):
  17. n = 10 #First data point
  18. # Run attempts with multiple iterations each
  19. iterations = 1000
  20. attempts = 6
  21. timess.append([])
  22. while(True):
  23. # Evaluate the performance
  24. localTimes = []
  25. for _ in range(attempts):
  26. # Initialize random data
  27. r_vec = np.random.rand(n, 3).astype(np.float64)
  28. if massive:
  29. m_vec = np.random.rand(n).astype(np.float64)
  30. else:
  31. m_vec = np.zeros(n).astype(np.float64)
  32. m_vec[0] = 1
  33. start = timer()
  34. for _ in range(iterations):
  35. functions[i](r_vec, m_vec)
  36. stop = timer()
  37. localTimes.append((stop - start)*1000/iterations) #in ms
  38. # Calculate mean and error
  39. # Discard high times since these are likely due to interferences
  40. localTimes = np.sort(localTimes)
  41. localTimes = localTimes[:attempts-2]
  42. print(localTimes, iterations)
  43. error = np.std(localTimes)/np.sqrt(attempts-1)
  44. timess[i].append([n, np.mean(localTimes), error])
  45. # Recalculate how many iterations would have been sensible
  46. iterations = int(timescale/np.mean(localTimes))
  47. if iterations > 1000: iterations = 1000
  48. if iterations < 1: break;
  49. # Increase the number of points
  50. n *= 2
  51. # Plot the results
  52. f, ax = plt.subplots(1, 1, figsize=(6, 4), sharey=True)
  53. for times, label, style, colour in zip(timess, labels, styles, colours):
  54. times = np.array(times)
  55. ax.errorbar(times[:,0], times[:,1], yerr=times[:,2],
  56. label=label, marker='+', linestyle=style, c=colour)
  57. ax.loglog()
  58. if massive:
  59. utils.setAxes(ax, x='Number of massive particles', y='Time / ms',
  60. xcoords=(.7, -0.1), ycoords=(-0.1,.7))
  61. else:
  62. utils.setAxes(ax, x='Number of massless particles', y='Time / ms',
  63. xcoords=(.7, -0.1), ycoords=(-0.1,.7))
  64. utils.stylizePlot([ax])
  65. ax.legend()
  66. ax.set_xlim((10, None))
  67. plt.show()
  68. file = open('data/performance.pickle', "wb")
  69. pickle.dump(timess, file)