1

고유 한 요소 조합을 만드는 코드가 있습니다. 6 가지 유형이 있으며 각각 약 100 가지가 있습니다. 그래서 100^6 조합이 있습니다. 각 조합을 계산하고 관련성을 검사 한 다음 폐기하거나 저장해야합니다.중첩 된 for-loops에 대한 최대 CPU 사용을 만드는 가장 쉬운 방법은 무엇입니까?

코드의 관련 비트는 다음과 같습니다

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_useful()'의 두 함수를 호출합니다. 나는 그것들을 분리 된 프로세스로 만들 수 있고 그것들을 for-loops와 동시에 실행할 수 있습니다.

for-loops는 어떨까요? 그 하나의 프로세스를 빠르게 할 수 있습니까? 왜냐하면 그것이 시간 소비가되는 곳이기 때문입니다. (< - 내 주요 질문입니다)

속임수가 있습니까? 예를 들어 C로 컴파일 한 다음 OS 다중 스레드를 자동으로 컴파일합니까?

이 방법으로 기능을 실행할 수 있습니다
+0

당신은 것입니다 :

은 비록 :)

그러나 첫 번째는 당신에게 두 번째

multiprocessing 문서에 무슨 일이 일어나고 있는지의 아이디어를 줄 것이다, 두 번째는 가장 쉬운 가정 해결책을 찾으려면 여기를 클릭하십시오 : https://stackoverflow.com/questions/5784389/using-100-of-all-cores-with-python-multiprocessing –

+0

for-loop를 파이프 라인에 넣을 수있는 방법을 모르겠습니다. 당신이 참조하는 그 anwser에서 행해지는 것입니다. 나는 그것을 이미 읽었지만 그것이 나를 도울 수있는 방법을 보지 못합니까? 설명 할 수 있니? –

+0

멀티 프로세싱 문서 (python의 표준 라이브러리) 나 라이브러리 joblib의 문서를 읽으십시오. 첫 번째 루프 크기가 ​​100이고 8 = 100 cpus이면이 외부 루프를 병렬 처리하십시오 (joblib의 첫 번째 예제는 충분해야합니다. 기본적으로 외부 루프를 제외한 모든 작업을 수행합니다.이 선험적으로 선택한 값은 다음과 같습니다. 논증). (또한 마지막 문장은 프로그래밍, OS, 프로세서와 관련하여 분명한 이해가 부족하다는 것을 보여줍니다. 먼저 소개 과정을 먼저 읽으십시오.) – sascha

답변

3

가 난 단지 다른 프로세스의 예를 볼 수는 없습니다 어떻게 하나 개의 프로세스

파이썬이 멀티 스레딩되어 멀티 쓰레드 GIL (Global Interpreter Lock) 때문에 매우 효과적이지 않습니다. 따라서 모든 프로세서 코어를 사용하려는 경우 동시성을 원하면 multiprocessing 모듈을 사용하여 여러 프로세스를 사용하는 것 외에 다른 선택의 여지가 없습니다 (물론이 문제없이 다른 언어를 사용할 수도 있습니다)

귀하의 경우에 사용을 멀티 프로세싱의

대략 예 :

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_NUMBER을 조정할 수 있습니다. multiprocessing.Pool와 같은

:

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

.map_async를 사용하고 싶습니다,하지만 난 당신이 프로그램을보다 효율적으로 제어 할 처음에 말을 .https://docs.python.org/3/library/multiprocessing.html