Os.sched_getapherity(0)与os.cpu_count() [英] os.sched_getaffinity(0) vs os.cpu_count()

查看:17
本文介绍了Os.sched_getapherity(0)与os.cpu_count()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我知道标题中这两种方法的区别,但不知道实际意义。

据我所知:如果您使用的NUM_Worker多于实际可用的内核,您将面临巨大的性能下降,因为您的操作系统不断来回切换以保持并行。我不知道这是不是真的,但我是从某个比我聪明的人那里读到的。

os.cpu_count()的文档中写着:

返回系统的CPU数量。如果未确定,则返回NONE。此数量不等于 当前进程可以使用。可以获得可用的CPU数量 WITH len(os.sched_getapherity(0))

因此,如果某个进程可以使用的CPU比系统中的CPU多,那么我想知道系统指的是什么。

我只想安全高效地实现multiprocessing.pool功能。所以我的问题总结如下:

NUM_WORKERS = os.cpu_count() - 1
# vs.
NUM_WORKERS = len(os.sched_getaffinity(0)) - 1

-1是因为我发现,如果我尝试在处理数据的同时工作,我的系统延迟会小很多。

推荐答案

如果您的任务是纯100%受CPU限制的,即只做计算,那么显然,如果进程池大小大于计算机上可用的CPU数量,则不会/不会获得任何好处。但是,如果有I/O的混合,进程将放弃CPU,等待I/O完成(或者,例如,从网站返回URL,这需要相对较长的时间),该怎么办?在我看来,在这种情况下,如果进程池大小超过os.cpu_count(),您是否无法实现更高的吞吐量,这一点我不清楚。

更新

以下是演示这一点的代码。这段代码使用的是进程,使用线程处理可能是最好的选择。我的台式机上有8个内核。该程序只需同时检索54个URL(在本例中为并行检索)。向程序传递一个参数,即要使用的池的大小。遗憾的是,仅创建其他进程就会产生初始开销,因此如果您创建了太多进程,节省的成本就会开始下降。但是,如果任务长时间运行并且有大量I/O,那么创建进程的开销最终将是值得的:

from concurrent.futures import ProcessPoolExecutor, as_completed
import requests
from timing import time_it

def get_url(url):
    resp = requests.get(url, headers={'user-agent': 'my-app/0.0.1'})
    return resp.text


@time_it
def main(poolsize):
    urls = [
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
        'https://ibm.com',
        'https://microsoft.com',
        'https://google.com',
    ]
    with ProcessPoolExecutor(poolsize) as executor:
        futures = {executor.submit(get_url, url): url for url in urls}
        for future in as_completed(futures):
            text = future.result()
            url = futures[future]
            print(url, text[0:80])
            print('-' * 100)

if __name__ == '__main__':
    import sys
    main(int(sys.argv[1]))

8进程:(我的核数):

func: main args: [(8,), {}] took: 2.316840410232544 sec.

16个进程:

func: main args: [(16,), {}] took: 1.7964842319488525 sec.

24个进程:

func: main args: [(24,), {}] took: 2.2560818195343018 sec.

这篇关于Os.sched_getapherity(0)与os.cpu_count()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆