๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป IT·๊ธฐ์ˆ ·ํ†ต๊ณ„

๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ (Multiprocessing) w/ Python

by nowgeun 2023. 1. 26.
728x90

๋น…๋ฐ์ดํ„ฐ๋กœ ์ž‘์—…ํ•  ๋•Œ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•

 

์‚ฌ์ด์ฆˆ๊ฐ€ ํฐ ๋ฐ์ดํ„ฐ๋กœ ์ž‘์—…ํ•  ๋•Œ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋งŽ์€ ์–‘์˜ ๊ณ„์‚ฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ๋Œ๋‹ค๊ฐ€ ์ค‘๊ฐ„์— ์—๋Ÿฌ๊ฐ€ ๋‚˜์„œ ๋ฉˆ์ถ˜๋‹ค๋˜๊ฐ€ ํ˜น์€ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐ ์˜ค๋žœ ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•  ๋•Œ ๋ฐ›๋Š” ์ŠคํŠธ๋ ˆ์Šค๋ž€... ๋จธ์‹ ๋Ÿฌ๋‹์ด๋‚˜ ๋”ฅ๋Ÿฌ๋‹ ๊ด€๋ จ ๋ชจ๋ธ๋ง ์ž‘์—…์„ ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋Ÿ‰์ด GB ๋‹จ์œ„๋ผ๋ฉด ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด์ฒ˜๋Ÿผ ๋ณต์žกํ•˜๊ณ  ์—ฐ์‚ฐ์ด ๋งŽ์ด ํ•„์š”ํ•œ ์ž‘์—…์˜ ์„ฑ๋Šฅ ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์—๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

 

1. Vertical Scaling (์ˆ˜์ง์  ์Šค์ผ€์ผ๋ง)

Vertical Scaling์€ ๋‹จ์ˆœํ•˜๊ฒŒ ์ปดํ“จํŒ… ํŒŒ์›Œ๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ์ข‹์€ ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ CPU์˜ ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๋“ฑ ๋” ๋‚˜์€ ํ•˜๋“œ์›จ์–ด๋ฅผ ๊ตฌ๋งคํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘์—… ์†๋„๋ฅผ ํ–ฅ์ƒ ์‹œํ‚ต๋‹ˆ๋‹ค. ์ž์ „๊ฑฐ ํ•œ ๋Œ€๋กœ ์ด์‚ฟ์ง์„ ๋‚˜๋ฅด๋Š” ๋Œ€์‹ ์— ์šฉ๋‹ฌ ํ•˜๋‚˜๋ฅผ ๋ถˆ๋Ÿฌ์„œ ์ง์„ ์˜ฎ๊ธฐ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

 

2. Horizontal Scaling (์ˆ˜ํ‰์  ์Šค์ผ€์ผ๋ง)

Horizontal Scaling์€ ์‹ญ์‹œ์ผ๋ฐ˜์˜ ๋ฐฉ์‹์œผ๋กœ ๋” ๋งŽ์€ ์ปดํ“จํŒ… ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘์—… ์„ฑ๋Šฅ์„ ๋†’์ž…๋‹ˆ๋‹ค. ์ด์‚ฟ์ง์„ ๋‚˜๋ˆ ์„œ ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ž์ „๊ฑฐ๋กœ ์ž‘์—…์„ ํ•˜๋Š” ์…ˆ์ด์ฃ 

๋น…๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ Vertical Scaling์€ ์ปดํ“จํŒ… ์ž์›์— ํˆฌ์ž๋ฅผ ๋งŽ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๊ฑด์ด ๋  ๊ฒฝ์šฐ์— ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ธˆ์ „์ ์ธ ๋ถ€๋ถ„์„ ๊ณ ๋ คํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ญ์ƒ ์ •๋‹ต์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” Horizontal Scaling ๋ฐฉ์‹์ธ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์„ ํ™œ์šฉํ•˜์—ฌ Python์˜ ์ž‘์—… ์†๋„๋ฅผ ๊ฐœ์„ ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

https://networknuts.net/understanding-vertical-scaling-horizontal-scaling/

 


๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ (Multiprocessing)

 

๋Œ€๋ถ€๋ถ„์˜ ์ปดํ“จํ„ฐ๋“ค์€ ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU๊ฐ€ ํƒ‘์žฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…์„ ํ•˜์ž๋ฉด CPU์•ˆ์— ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ž์ „๊ฑฐ๊ฐ€ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ Python์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋Œ๋ฆฌ๋ฉด ํ•œ๊ฐœ์˜ ์ฝ”์–ด๊ฐ€ ๊ทธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ฝ”์–ด์—๊ฒŒ ์ž‘์—…์„ ๊ท ๋“ฑํ•˜๊ฒŒ ๋‚˜๋ˆ ์ค˜์„œ ์ž‘์—…์ฒ˜๋ฆฌ ์†๋„๋ฅผ ๋น ๋ฅด๊ฒŒ ํ•˜๋Š” ํ–‰์œ„์ž…๋‹ˆ๋‹ค.

 

 

์ œ๊ฐ€ ๋Œ€ํ•™์ƒ์ด๋˜ ์‹œ์ ˆ, ์•„๋ž˜์˜ ์งค์ด ํฌ๊ฒŒ ์œ ํ–‰ํ–ˆ์—ˆ๋˜ ๊ฒƒ์œผ๋กœ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ๋น„์œ ๊ฐ€ ์›Œ๋‚™ ์ฐฐ๋–ก์ด๋ผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.


Python์œผ๋กœ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ (Multiprocessing)

 

Python์—๋Š” ์ž์ฒด์ ์œผ๋กœ ๋‚ด์žฅ๋œ ํ•จ์ˆ˜ multiprocessing ์ด ์žˆ์Šต๋‹ˆ๋‹ค. pip๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋”ฐ๋กœ ์„ค์น˜๊ฐ€ ํ•„์š”์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์šฐ์„  ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ ์—†์ด 1๋ถ€ํ„ฐ 2000๊นŒ์ง€์˜ ํŒฉํ† ๋ฆฌ์–ผ์„ ๊ณ„์‚ฐํ•˜๋Š” ์ž‘์—…์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

[Input]

import time

# starting time
start = time.time()

# save the factorial results here
s_results = []

# add all integers from 1 to 1_000_000
def factorial(i):
    x = 1
    for k in range(1,i+1):
        x = x*k
    results.append(x)

# number of test cases
cases = [x for x in range(0,2001)]
for c in cases:
    factorial(c)

print("%s seconds" % (time.time()-start))

[Output]

> 0.5778999328613281 seconds

 

์ด์ œ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์„ ์‚ฌ์šฉํ•ด์„œ ๊ณ„์‚ฐ์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

[Input]

import multiprocessing as mp
import time

# starting time
start = time.time()

# save the factorial results here
p_results = []

# calculate factorial of a number
def factorial(i):
    x = 1
    for k in range(1,i+1):
        x = x*k
    p_results.append(x)

# factorials from 1 to 2000
cases = [x for x in range(1,2001)]

######################
### ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ   ###
pool = mp.Pool(processes=5) # ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์ฝ”์–ด ํ”„๋กœ์„ธ์„œ์˜ ์ˆ˜
pool.map(factorial, cases)
pool.close()
pool.join()
######################

print("%s seconds" % (time.time()-start))

[Output]

0.222374095917 seconds

์ž‘์—… ์†๋„๊ฐ€ 2๋ฐฐ ์ด์ƒ์œผ๋กœ ํ™•์‹คํžˆ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค. 

 

 

!! ์ฃผ์˜์  !!

ํ•˜์ง€๋งŒ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ•ญ์ƒ ์ž‘์—…์†๋„๊ฐ€ ๋นจ๋ผ์ง€๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์„ ํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, ์ž‘์—…์„ ๋‚˜๋ˆ ์„œ ๊ฐ ํ”„๋กœ์„ธ์„œ์— ํ• ๋‹นํ•˜๋Š” ์‹œ๊ฐ„์ด ์ถ”๊ฐ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด์‚ฟ์ง์ด ๋‹ฌ๋ž‘ ๋ฐ•์Šค 1๊ฐœ ์ธ๋ฐ, ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ž์ „๊ฑฐ๋กœ ๋‚˜๋ฅด๊ธฐ ์œ„ํ•ด์„œ 4๋Œ€์˜ ๋ฐ•์Šค๋กœ ๋‚˜๋ˆˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์„ธ์š”. ์˜ˆ ์‹œ๊ฐ„๋‚ญ๋น„์ž…๋‹ˆ๋‹ค. 

 

์ดํ•ด๊ฐ€ ์•ˆ๋˜์‹ ๋‹ค๋ฉด ์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค:

 

[Input]

import multiprocessing as mp
import seaborn as sns
import pandas as pd
import time

# calculate factorial of a number
def factorial(i):
    x = 1
    for k in range(1,i+1):
        x = x*k

# measuring computation time for seq and parallel
seq_times = []
prl_times = []

for i in range(101,2501):
    cases = [x for x in range(1,i)]
  
  # Sequential  ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ X
  # starting time
    seq_start = time.time()
    for c in cases:
        factorial(c)
    seq_times.append(time.time()-seq_start)
        
  # Parallel    ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ O
    prl_start = time.time()
    pool = mp.Pool(processes=5) # Number of processes that you want to use
    pool.map(factorial, cases)
    pool.close()
    pool.join()
    prl_times.append(time.time()-prl_start)
   
   
fac = [i for i in range(101,2501)]

df = pd.DataFrame(data={"upper limit":fac,
                        "sequential":seq_times,
                        "parallel":prl_times})

df = df.melt(id_vars="upper limit",value_name="time",var_name="processing type")

sns.set(rc={'figure.figsize':(15,8)})
ax = sns.lineplot(x=df["upper limit"], y=df["time"], hue=df["processing type"])
ax.axes.set_title("Sequential vs Parallel processing time of factorial() function",fontsize=18)
ax.set_xlabel("Upperbound of calculated factorials",fontsize=15)
ax.set_ylabel("Time (sec)",fontsize=15)

[Output]

 

1๋ถ€ํ„ฐ 1100 ์ด์ƒ์˜ ํŒฉํ† ๋ฆฌ์–ผ์„ ๊ณ„์‚ฐํ•  ๋•Œ ๋ฉ€ํ‹ฐํ”„๋กœ์„ธ์‹ฑ์ด ๋” ๋น ๋ฅธ ์ž‘์—…๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์•„๋ž˜ ๋ฒ”์œ„์˜ ์ž‘์—…์€ ์ „๋ถ€ ์ด์‚ฟ์ง ํ•œ ๋ฐ•์Šค๋ฅผ ๋„ค ๋ฐ•์Šค๋กœ ๊ตณ์ด ๋‚˜๋ˆ ๋‹ด๊ธฐ๋•Œ๋ฌธ์— ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.


์ •๋ฆฌํ•˜๊ธฐ

๋น…๋ฐ์ดํ„ฐ ํ™˜๊ฒฝ์—์„œ๋Š” ๋น ๋ฅธ ์ž‘์—…์†๋„๋ฅผ ์œ„ํ•ด ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ๋ชจ๋‘ ์ž˜ ํ™œ์šฉํ•˜์…”์„œ ์นผํ‡ดํ•˜์‹œ๊ธธ ๋ฐ”๋ผ๊ฒ ์Šต๋‹ˆ๋‹ค :)

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€