Monte Carlo 模拟:为什么随机点数越少处理时间越长?
Monte Carlo Simulation: Why is the processing time greater for a smaller number of random points?
我正在编写一个 Monte Carlo 模拟来估计 Pi 的值,并且我正在记录每个连续点数所需的总处理时间为 运行 秒。奇怪的是,处理时间似乎开始随着每个 运行 而减少,然后随着点数的增加而随着每个 运行 而增加。我已经用 perf_counter()、time()、clock() 和 default_timer() 对此进行了测试。我也尝试使用 CPU 时钟函数(如 process_time() 和 thread_time() 进行测试,但对于大多数 运行s,它 return将总处理时间设为 0.0。
为什么CPU定时器总时间return0.0,而时钟定时器有这样奇怪的趋势?我希望处理时间线性增加,但显然情况并非如此,除非我的代码某处存在问题。我已经包含了我的代码和情节作为示例。
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
import time
import math
#Plot number of points vs fractional error of pi)
def piPlot(piList):
#Set correct plot size
piAx = plt.gca()
piAx.set_aspect(1)
#Generate and label plot, set to logarithmic scale
plt.scatter(N,piList)
plt.xscale("log")
plt.yscale("log")
plt.title('Fractional Error vs Number of Points')
plt.xlabel('Number of Points [Logarithmic]')
plt.ylabel('Fractional Error [Logarithmic]')
#Plot generator for number of points vs processing time
def timePlot(timeList):
#Set correct plot size
timeAx = plt.gca()
timeAx.set_aspect(1)
#Generate and label plot, set to logarithmic scale
plt.scatter(N,timeList)
plt.xscale("log")
plt.yscale("log")
plt.title('Processing Time vs Number of Points')
plt.xlabel('Number of Points [Logarithmic]')
plt.ylabel('Processing Time [Logarithmic]')
def simulation(n, t):
#Begin timer
startTime = t
#Initialize list for current run
run = []
#Generate random points, find number inside circle
xPoint = np.random.rand(n)
yPoint = np.random.rand(n)
total = ((xPoint ** 2) + (yPoint ** 2) <= 1).sum()
#Estimate pi
pi = 4*(total/n)
run.append(pi)
#End timer, calculate total processing itme
endTime = time.perf_counter()
T = endTime - startTime
run.append(T)
return run
def main():
#Define the total numbers of points for each simulation
N = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
#Run the simulation and calculate fractional error for returned pi
results1 = [simulation(i, time.perf_counter()) for i in N]
pis1, times1 = map(list, zip(*results1))
error1 = [abs((math.pi - i)/math.pi) for i in pis1]
#Generate plots
plot1 = plt.figure(1)
piPlot(error1)
plot2 = plt.figure(2)
timePlot(times1)
main()
Plot for Processing Time vs Number of Points
试试
N = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1]
您将看到以下结果:
n = 1 t = 6.614800076931715e-05
n = 10 t = 2.7269999918644316e-05
n = 100 t = 2.177599981223466e-05
n = 1000 t = 4.9498999942443334e-05
n = 10000 t = 0.00042855599986069137
n = 100000 t = 0.0026685809998525656
n = 1000000 t = 0.021433439000247745
n = 10000000 t = 0.19109468099941296
n = 1000000 t = 0.019547208999938448
n = 100000 t = 0.0036834789998465567
n = 10000 t = 0.0002759440003501368
n = 1000 t = 3.2883999665500596e-05
n = 100 t = 1.4722999367222656e-05
n = 10 t = 1.0972000382025726e-05
n = 1 t = 1.0822999684023671e-05
和编译代码有关。在你第一次调用你的函数后,代码就被编译了。所以第一次调用需要很长时间做初始处理。对于小 n
,内存管理的时间与计算本身相当。
我正在编写一个 Monte Carlo 模拟来估计 Pi 的值,并且我正在记录每个连续点数所需的总处理时间为 运行 秒。奇怪的是,处理时间似乎开始随着每个 运行 而减少,然后随着点数的增加而随着每个 运行 而增加。我已经用 perf_counter()、time()、clock() 和 default_timer() 对此进行了测试。我也尝试使用 CPU 时钟函数(如 process_time() 和 thread_time() 进行测试,但对于大多数 运行s,它 return将总处理时间设为 0.0。
为什么CPU定时器总时间return0.0,而时钟定时器有这样奇怪的趋势?我希望处理时间线性增加,但显然情况并非如此,除非我的代码某处存在问题。我已经包含了我的代码和情节作为示例。
import numpy as np
from numpy import random
import matplotlib.pyplot as plt
import time
import math
#Plot number of points vs fractional error of pi)
def piPlot(piList):
#Set correct plot size
piAx = plt.gca()
piAx.set_aspect(1)
#Generate and label plot, set to logarithmic scale
plt.scatter(N,piList)
plt.xscale("log")
plt.yscale("log")
plt.title('Fractional Error vs Number of Points')
plt.xlabel('Number of Points [Logarithmic]')
plt.ylabel('Fractional Error [Logarithmic]')
#Plot generator for number of points vs processing time
def timePlot(timeList):
#Set correct plot size
timeAx = plt.gca()
timeAx.set_aspect(1)
#Generate and label plot, set to logarithmic scale
plt.scatter(N,timeList)
plt.xscale("log")
plt.yscale("log")
plt.title('Processing Time vs Number of Points')
plt.xlabel('Number of Points [Logarithmic]')
plt.ylabel('Processing Time [Logarithmic]')
def simulation(n, t):
#Begin timer
startTime = t
#Initialize list for current run
run = []
#Generate random points, find number inside circle
xPoint = np.random.rand(n)
yPoint = np.random.rand(n)
total = ((xPoint ** 2) + (yPoint ** 2) <= 1).sum()
#Estimate pi
pi = 4*(total/n)
run.append(pi)
#End timer, calculate total processing itme
endTime = time.perf_counter()
T = endTime - startTime
run.append(T)
return run
def main():
#Define the total numbers of points for each simulation
N = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]
#Run the simulation and calculate fractional error for returned pi
results1 = [simulation(i, time.perf_counter()) for i in N]
pis1, times1 = map(list, zip(*results1))
error1 = [abs((math.pi - i)/math.pi) for i in pis1]
#Generate plots
plot1 = plt.figure(1)
piPlot(error1)
plot2 = plt.figure(2)
timePlot(times1)
main()
Plot for Processing Time vs Number of Points
试试
N = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1]
您将看到以下结果:
n = 1 t = 6.614800076931715e-05
n = 10 t = 2.7269999918644316e-05
n = 100 t = 2.177599981223466e-05
n = 1000 t = 4.9498999942443334e-05
n = 10000 t = 0.00042855599986069137
n = 100000 t = 0.0026685809998525656
n = 1000000 t = 0.021433439000247745
n = 10000000 t = 0.19109468099941296
n = 1000000 t = 0.019547208999938448
n = 100000 t = 0.0036834789998465567
n = 10000 t = 0.0002759440003501368
n = 1000 t = 3.2883999665500596e-05
n = 100 t = 1.4722999367222656e-05
n = 10 t = 1.0972000382025726e-05
n = 1 t = 1.0822999684023671e-05
和编译代码有关。在你第一次调用你的函数后,代码就被编译了。所以第一次调用需要很长时间做初始处理。对于小 n
,内存管理的时间与计算本身相当。