Чтобы увеличить скорость работы моего Mac на Python, я использую функцию fork. Мой Mac имеет 4 ядра, и я заметил, что если я использую 4 вилки, моя программа ускоряется в 3,7 раза. Любые дополнительные вилки не делают программу быстрее. Я даже не уверен, зависит ли успешное разветвление от количества ядер или нет, на самом деле я очень мало знаю о том, что на самом деле происходит, я просто знаю, что это работает. Я понимаю, что в gcloud vCPU = 5 не обязательно означает, что есть 5 ядер, но я надеялся, что большее количество процессоров поможет процессу разветвления ускориться. В любом случае, я установил следующую программу на Python на компьютер с 16 vCPU gcloud и не увидел увеличения скорости. Следующая программа просто насчитывает до 250 000 000. При использовании 4-х вилок на моем Mac это занимает 16 секунд, а при использовании 16-ти вилок в 16-ти виртуальных облаках vCPU - 18 секунд.
import functools, time, os
p = print
def print_intervals(number, interval, fork=None, total=0, print=True):
if number > 0 and number % interval == 0 and number >= interval:
if total:
per = int((number / total) * 100)
number = f"{number} - {per}%"
if fork == None:
p(number)
else:
p(f"fork {fork}")
p(number)
return
def timer(func):
"""Print the runtime of the decorated function"""
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
run_time = round(run_time, 2)
print(f"Finished {func.__name__!r} in {run_time} secs")
return value
return wrapper_timer
@timer
def temp1(**kwargs):
start = kwargs['start']
stop = kwargs['stop']
fork_num = kwargs['fork_num']
for x in range(start, stop):
print_intervals(x, 10_000_000)
z = x + 1
p(f'done fork {fork_num}')
def divide_range(divisions: int, total: int, idx: int):
sec = total // divisions
start = idx * sec
if total % divisions != 0 and idx == divisions:
stop = total
else:
stop = start + sec
return start, stop
def main_fork(func, total, **kwargs):
forks = 16
fake = kwargs.get("fake")
for i in range(forks):
start1, stop1 = 0, 0
if total != -1:
start1, stop1 = divide_range(forks, total, i)
p(f'fork num {i} {start1} {stop1}')
if not fake:
newpid = os.fork()
kwargs['start'] = start1
kwargs['stop'] = stop1
kwargs['fork_num'] = i
if fake and i > 0:
pass
elif fake:
func(**kwargs)
elif newpid == 0:
child(func, **kwargs)
return
def child(func, **kwargs):
func(**kwargs)
os._exit(0)
main_fork(temp1, 250_000_000, **{})