簡體   English   中英

為什么我的 python 代碼沒有使用所有的 cpu?

[英]why isn't my python code using all of the cpu?

我寫了一個簡單的 python 代碼,它只是不停地打印素數,但它只使用了我筆記本電腦 CPU 的 25%(100% 的單核)。 但我希望它使用所有的核心。 那可能嗎? 順便說一句,這里是代碼:

x = 10
while True:
    for num in range(1, x):
        flag = False
        if x > 1:
            for i in range(2, x):
                if (x % i) == 0:
                    flag = True
                    break
        if not flag:
            print(x, "is a prime number")
            break
    x += 1

這就引出了一個問題:你是如何測量你的程序使用了多少 CPU 的?

這是我的 macOS 機器的屏幕截圖,運行您的程序:

在此處輸入圖像描述

這里是 Linux 虛擬機上的htop屏幕截圖:

在此處輸入圖像描述

換句話說,您的程序將愉快地消耗盡可能多的單個 CPU 內核,因為它是單線程的。

編輯

為了使您的程序使用普通的 Python 消耗所有內核,不幸的是,由於全局解釋器鎖 (GIL)使得基於 Python 的並行 CPU 工作效率非常低,因此線程不會不幸地切斷它。

令人高興的是,這就是multiprocessing模塊介入的地方; 它協調多個不受共享鎖阻礙的獨立 Python進程 你可以看到這個程序已經相當復雜了,但確實設法使我機器上的所有 16 個內核飽和。

在此處輸入圖像描述

由於工人們查看的是 integer 范圍的不同部分,因此該程序打印的結果將完全沒有嚴格的順序。

import multiprocessing
import queue
from itertools import count


def is_prime(x):
    for i in range(2, x // 2 + 1):
        if x % i == 0:
            return False
    return True


def prime_loop(result_queue: multiprocessing.Queue, start: int, step: int):
    for i in count(start, step):
        if is_prime(i):
            result_queue.put((i, True))


def main():
    result_queue = multiprocessing.Queue()
    num_workers = multiprocessing.cpu_count()
    workers = []
    for i in range(num_workers):
        # Since there's no point in starting a worker that would look at even numbers,
        # we start the first worker at 1 and the second worker at 3, etc.
        start = i * 2 + 1
        # Each worker will step over by the number of workers + 1, so e.g. if there are 4 workers,
        # worker 1 will check 1, 5, 11, 16,
        # worker 2 will check 2, 6, 12, 17,
        # worker 3 will check 3, 7, 13, 18,
        # worker 4 will check 4, 8, 14, 19 etc.
        step = num_workers + 1
        worker = multiprocessing.Process(
            target=prime_loop, args=(result_queue, start, step)
        )
        worker.start()
        workers.append(worker)
    seen = set()
    while True:
        try:
            number, result = result_queue.get(timeout=0.1)
            if result:
                if number in seen:
                    raise NotImplementedError("bug :(")
                seen.add(number)
                print(f"{number} is a prime number")
        except KeyboardInterrupt:
            break
        except (multiprocessing.TimeoutError, queue.Empty):
            pass
    for worker in workers:
        worker.kill()


if __name__ == "__main__":
    main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM