如何使用gcloud的多CPU来使用Python加快程序运行速度?

时间:2019-10-25 01:43:37

标签: python google-cloud-platform

为了使用Python在Mac上提高速度,我使用了fork功能。我的mac有4个内核,我注意到如果使用4个fork,我的程序速度将提高3.7倍。任何其他派生不会使程序更快。我什至不确定成功的分叉是否依赖于内核的数量,实际上我对真正发生的事情了解得很少,我只是知道它是有效的。我意识到在gcloud上vCPU = 5并不一定意味着有5个内核,但是我希望更多的CPU能够以某种方式帮助分叉过程更快地进行。无论如何,我将以下python程序放在16 vCPU gcloud计算机上,但速度没有增加。以下程序最多可计数250,000,000。在Mac上使用4个fork需要16秒,但是在16个vCPU gcloud上使用16个fork需要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, **{})

2 个答案:

答案 0 :(得分:0)

我再次尝试了,这一次它起作用了。一台16 vCPU N1机器将程序加速了5倍。我不确定我做了什么不同,但是我唯一能想到的是,当我以为使用16 vCPU时,我实际上是在使用1 vCPU计算机电脑。

答案 1 :(得分:0)

不过,您可能想看看内置的 1.0680423599551432 0.28135157003998756 0.19099885696778074 库。

Python 是在多核 CPU 出现之前创建的,因此它运行在一个线程上 - 无论您运行多少个 multiprocessing 实例。

使用 threading.Thread 库时,您可以有效地运行 Python x 次。例如,您将在 CPU 的每个内核上运行不同的 Python 实例,以在一定程度上加快速度。