Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使嵌套for循环的cpu使用率达到最大的最简单方法是什么?_Python_Multithreading_Optimization_Multiprocessing_Nested Loops - Fatal编程技术网

Python 使嵌套for循环的cpu使用率达到最大的最简单方法是什么?

Python 使嵌套for循环的cpu使用率达到最大的最简单方法是什么?,python,multithreading,optimization,multiprocessing,nested-loops,Python,Multithreading,Optimization,Multiprocessing,Nested Loops,我有一些代码,可以生成元素的独特组合。有6种类型,每种大约有100种。所以有100^6个组合。必须计算每个组合,检查其相关性,然后丢弃或保存 代码的相关部分如下所示: def modconffactory(): for transmitter in totaltransmitterdict.values(): for reciever in totalrecieverdict.values(): for processor in totalprocessordict.va

我有一些代码,可以生成元素的独特组合。有6种类型,每种大约有100种。所以有100^6个组合。必须计算每个组合,检查其相关性,然后丢弃或保存

代码的相关部分如下所示:

def modconffactory():
for transmitter in totaltransmitterdict.values():
    for reciever in totalrecieverdict.values():
        for processor in totalprocessordict.values():
            for holoarray in totalholoarraydict.values():
                for databus in totaldatabusdict.values():
                    for multiplexer in totalmultiplexerdict.values():
                        newconfiguration = [transmitter, reciever, processor, holoarray, databus, multiplexer]
                        data_I_need = dosomethingwith(newconfiguration)
                        saveforlateruse_if_useful(data_I_need)
现在这需要很长时间,这很好,但现在我意识到这个过程(进行配置,然后计算以供以后使用)一次只使用8个处理器内核中的1个

我一直在阅读有关多线程和多处理的内容,但我只看到了不同进程的示例,而没有看到如何多线程处理一个进程。在我的代码中,我调用了两个函数:“dosomethingwith()”和“saveforlateruse_if_usable()”。我可以把它们分成单独的进程,让它们与for循环并发运行,对吗


但是for循环本身呢?我能加快这个过程吗?因为这就是时间消耗的地方。(您可以通过以下方式运行函数:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
   p = Pool(5)
   print(p.map(f, [1, 2, 3]))

我只看到不同进程的示例,而没有看到如何对一个进程执行多线程

Python中有多线程,但由于GIL(全局解释器锁)的存在,它的效率非常低。因此,如果您想要使用所有处理器内核,如果您想要并发,那么除了使用多个进程之外别无选择,这可以通过
多处理
模块完成(好吧,你也可以使用另一种语言而不会出现这样的问题)

您的案例的多处理使用的近似示例:

import multiprocessing

WORKERS_NUMBER = 8

def modconffactoryProcess(generator, step, offset, conn):
    """
    Function to be invoked by every worker process.

    generator: iterable object, the very top one of all you are iterating over, 
    in your case, totalrecieverdict.values()

    We are passing a whole iterable object to every worker, they all will iterate 
    over it. To ensure they will not waste time by doing the same things 
    concurrently, we will assume this: each worker will process only each stepTH 
    item, starting with offsetTH one. step must be equal to the WORKERS_NUMBER, 
    and offset must be a unique number for each worker, varying from 0 to 
    WORKERS_NUMBER - 1

    conn: a multiprocessing.Connection object, allowing the worker to communicate 
    with the main process
    """
    for i, transmitter in enumerate(generator):
        if i % step == offset:
            for reciever in totalrecieverdict.values():
                for processor in totalprocessordict.values():
                    for holoarray in totalholoarraydict.values():
                        for databus in totaldatabusdict.values():
                            for multiplexer in totalmultiplexerdict.values():
                                newconfiguration = [transmitter, reciever, processor, holoarray, databus, multiplexer]
                                data_I_need = dosomethingwith(newconfiguration)
                                saveforlateruse_if_useful(data_I_need)
    conn.send('done')


def modconffactory():
    """
    Function to launch all the worker processes and wait until they all complete 
    their tasks
    """
    processes = []
    generator = totaltransmitterdict.values()
    for i in range(WORKERS_NUMBER):
        conn, childConn = multiprocessing.Pipe()
        process = multiprocessing.Process(target=modconffactoryProcess, args=(generator, WORKERS_NUMBER, i, childConn))
        process.start()
        processes.append((process, conn))
    # Here we have created, started and saved to a list all the worker processes
    working = True
    finishedProcessesNumber = 0
    try:
        while working:
            for process, conn in processes:
                if conn.poll():  # Check if any messages have arrived from a worker
                    message = conn.recv()
                    if message == 'done':
                        finishedProcessesNumber += 1
            if finishedProcessesNumber == WORKERS_NUMBER:
                working = False
    except KeyboardInterrupt:
        print('Aborted')
您可以根据您的需要调整
WORKERS\u NUMBER

与多处理池相同:

import multiprocessing

WORKERS_NUMBER = 8

def modconffactoryProcess(transmitter):
    for reciever in totalrecieverdict.values():
        for processor in totalprocessordict.values():
            for holoarray in totalholoarraydict.values():
                for databus in totaldatabusdict.values():
                    for multiplexer in totalmultiplexerdict.values():
                        newconfiguration = [transmitter, reciever, processor, holoarray, databus, multiplexer]
                        data_I_need = dosomethingwith(newconfiguration)
                        saveforlateruse_if_useful(data_I_need)


def modconffactory():
    pool = multiprocessing.Pool(WORKERS_NUMBER)
    pool.map(modconffactoryProcess, totaltransmitterdict.values())
您可能希望使用
.map\u async
而不是
.map

这两个代码段的作用相同,但我想说的是,在第一个代码段中,您对程序有更多的控制

不过,我想第二个是最简单的:)

但是第一个应该让你知道第二个发生了什么


multiprocessing
docs:

您可以在这里找到您的解决方案:我不知道如何将for循环放入管道中,就像您所指的anwser中所做的那样。我已经读过了,但我不知道这对我有什么帮助?您能解释一下吗?请阅读multiprocessing docs(python的标准库)或者库joblib的文档。由于第一个循环的大小为100,您有8个循环,您是否对代码进行了分析,以查看它在哪里花费了大部分时间?我认为它应该位于
dosomethingwith(新配置)中
调用。如果是这种情况,您可以将其作为单独的进程运行,并让这些进程将其结果放入与主进程共享的
队列中。