Как вы используете несколько процессоров gcloud для ускорения вашей программы с Python? - PullRequest
0 голосов
/ 25 октября 2019

Чтобы увеличить скорость работы моего 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, **{})

1 Ответ

0 голосов
/ 27 октября 2019

Я попробовал еще раз, и на этот раз это сработало. Машина с 16 vCPU N1 ускорила программу в 5 раз. Я не уверена, что я сделала по-другому, но единственное, о чем я могу думать, это то, что я фактически использовала компьютер с 1 vCPU, когда думала, что я использую 16 vCPUкомпьютер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...