multiprocessing을 Joblib으로 바꿔보자
from joblib import Parallel, delayed
t1=time.time()
nbr_in_quarter_unit_circles2=Parallel(n_jobs=nbr_parallel_blocks, verbose=1) \
(delayed(estimate_nbr_points_in_quarter_circle)(nbr_samples_per_worker)\
for sample_idx in range(nbr_parallel_blocks))
# Parallel - n_job 매개변수 - 프로세스 실행 갯수 지정
# Parallel에는 iterable 을 매개변수로 받는 __call__호출 가능 메서드가 있음
# 괄호 안에 iterable (...for sample_idx in range(nbr_parallel_blocks)) 을 넘기는 것
# 호출 가능 메서드는 각 delayed(estimate_nbr_points_in_quarter_circle) 함수를 반복하면서 함수 실행을 인자에 묶음으로 넘긴다
# (nbr_samples_per_worker)
t2=time.time()
print(nbr_in_quarter_unit_circles)
pi_estimate=sum(nbr_in_quarter_unit_circles2)*4/float(nbr_samples_in_total)
print("Estimated pi", pi_estimate)
print("Delta:", t2-t1)
[Parallel(n_jobs=6)]: Using backend LokyBackend with 6 concurrent workers.
[Parallel(n_jobs=6)]: Done 2 out of 6 | elapsed: 11.5s remaining: 23.0s
[Parallel(n_jobs=6)]: Done 6 out of 6 | elapsed: 11.6s finished
[13088998, 13090624, 13088555, 13091653, 13093314, 13089257]
Estimated pi 3.14165232
Delta: 11.658189058303833
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3294
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3295
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3291
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3290
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3292
Executing estimate_nbr_points_in_quarter_circle
with 16,666,666.666666666 on pid 3293
from joblib import Memory
memory=Memory("./joblib_cache", verbose=0)
@memory.cache
def estimate_nbr_points_in_quarter_circle_with_idx(nbr_estimates, idx):
print(f"""Executing estimate_nbr_points_in_qurter_circle with
{nbr_estimates} on sample {idx} on pid {os.getpid()}""")
nbr_trials_in_quarter_unit_circle=0
for step in range(int(nbr_estimates)):
x=random.uniform(0,1)
y=random.uniform(0,1)
is_in_unit_circle=x*x+y*y<=1.0
nbr_trials_in_quarter_unit_circle+=is_in_unit_circle
return nbr_trials_in_quarter_unit_circle
# 앞에서 실행한 def estimate_nbr_points_in_quarter_circle 이 함수는 서로 구분할 수 있는 인잣값을 전달하지 않음
# nbr_estimates 를 호출할 떄마다 호출 시그니쳐가 같아서 항상 같은 결과를 얻게 됨
# 그래서 인자값에 호출 인덱스를 받도록 함수를 재정의
t1=time.time()
nbr_in_quarter_unit_circles=Parallel(n_jobs=nbr_parallel_blocks) \
(delayed(estimate_nbr_points_in_quarter_circle_with_idx) \
(nbr_samples_per_worker, idx) for idx in range(nbr_parallel_blocks))
t2=time.time()
print(nbr_in_quarter_unit_circles)
pi_estimate=sum(nbr_in_quarter_unit_circles)*4/float(nbr_samples_in_total)
print("Estimated pi", pi_estimate)
print("Delta:", t2-t1)
output
[13091606, 13089706, 13090371, 13092312, 13090225, 13088439]
Estimated pi 3.14170636
Delta: 11.370219945907593
t1=time.time()
nbr_in_quarter_unit_circles=Parallel(n_jobs=nbr_parallel_blocks) \
(delayed(estimate_nbr_points_in_quarter_circle_with_idx) \
(nbr_samples_per_worker, idx) for idx in range(nbr_parallel_blocks))
t2=time.time()
print(nbr_in_quarter_unit_circles)
pi_estimate=sum(nbr_in_quarter_unit_circles)*4/float(nbr_samples_in_total)
print("Estimated pi", pi_estimate)
print("Delta:", t2-t1)
output
[13091606, 13089706, 13090371, 13092312, 13090225, 13088439]
Estimated pi 3.14170636
Delta: 0.010504961013793945