다중 코어/다중 CPU 시스템에 루프의 함수 호출을 병렬로 처리하도록 어떻게 지시합니까?

StackOverflow https://stackoverflow.com/questions/56769

  •  09-06-2019
  •  | 
  •  

문제

저는 현재 데이터베이스에서 많은 양의 데이터를 로드하고 상황에 따라 다양한 계산을 통해 훨씬 더 작은 세트로 줄이는 하나의 모듈이 있는 애플리케이션을 설계 중입니다.

보다 집약적인 작업 중 다수는 결정론적으로 동작하며 병렬 처리에 적합합니다.

db에서 도착하는 많은 수의 데이터 청크를 반복하고 각 청크에 대해 부작용 없이 결정적 함수를 호출하는 루프가 있다면 프로그램이 함수가 반환될 때까지 기다리지 않고 오히려 설정하도록 어떻게 만들 수 있습니까? 다음 호출이 진행되므로 병렬로 처리될 수 있습니까?원칙을 설명하기 위한 순진한 접근 방식이 지금은 나에게 도움이 될 것입니다.

저는 Google의 MapReduce 문서를 읽었으며 여러 곳에서 전반적인 원칙을 사용할 수 있지만 지금은 대규모 클러스터를 대상으로 하지 않고 버전 1.0의 경우 단일 멀티 코어 또는 멀티 CPU 시스템을 대상으로 할 것입니다. .그래서 현재는 실제로 라이브러리를 사용할 수 있는지, 아니면 간단한 기본 버전을 직접 굴려야 할지 잘 모르겠습니다.

나는 디자인 프로세스의 초기 단계에 있으며 지금까지 내 언어로 C-무언가(속도가 중요한 비트)와 Python(생산성이 중요한 비트)을 목표로 삼고 있습니다.타당한 이유가 있는 경우 전환할 수도 있지만 지금까지는 내 선택에 만족합니다.

현재 청크를 처리하는 것보다 데이터베이스에서 다음 청크를 검색하는 데 더 오랜 시간이 걸릴 수 있으며 전체 프로세스가 I/O 바인딩된다는 사실을 알고 있습니다.그러나 지금은 실제로는 DB 클러스터나 메모리 캐싱 등을 사용하여 이 시점에서 I/O 바인딩되지 않는다고 가정합니다.

도움이 되었습니까?

해결책

여기서 뭔가 빠졌을 수도 있지만 pthread를 사용하면 상당히 간단해 보입니다.

N개의 스레드가 포함된 작은 스레드 풀을 설정하고 이를 모두 제어하는 ​​하나의 스레드를 갖습니다.

마스터 스레드는 단순히 다음과 같은 작업을 수행하는 루프에 있습니다.

  1. DB에서 데이터 청크 가져오기
  2. 다음 여유 스레드 찾기 여유 스레드가 없으면 기다리십시오.
  3. 작업자 스레드에 청크 넘겨주기
  4. 돌아가서 DB에서 다음 청크를 가져옵니다.

그 동안 작업자 스레드는 앉아서 다음 작업을 수행합니다.

  1. 내 자신을 무료로 표시
  2. 마스트 스레드가 나에게 데이터 덩어리를 제공할 때까지 기다리십시오.
  3. 데이터 덩어리 처리
  4. 다시 무료로 표시

이를 구현하는 방법은 두 개의 뮤텍스 제어 배열만큼 간단할 수 있습니다.하나는 작업된 스레드(스레드 풀)를 갖고 있고 다른 하나는 해당 스레드가 사용 가능한지 바쁜지 여부를 나타냅니다.

원하는대로 N을 조정하십시오 ...

다른 팁

글쎄, .net이 옵션이라면 그들은 많은 노력을 기울였습니다. 병렬 컴퓨팅.

여전히 Python을 사용할 계획이라면 다음을 살펴보는 것이 좋습니다. 처리.병렬 컴퓨팅(Python GIL로 인해)을 위해 스레드 대신 프로세스를 사용하고 "작업 항목"을 여러 프로세스에 배포하기 위한 클래스를 제공합니다.pool 클래스를 사용하면 다음과 같은 코드를 작성할 수 있습니다.

import processing

def worker(i):
    return i*i
num_workers = 2
pool = processing.Pool(num_workers)
result = pool.imap(worker, range(100000))

이는 호출을 프로세스에 분산시키는 itertools.imap의 병렬 버전입니다.풀의 apply_async 메서드를 사용하고 지연 결과 개체를 목록에 저장할 수도 있습니다.

results = []
for i in range(10000):
    results.append(pool.apply_async(worker, i))

자세한 내용은 다음을 참조하세요. Pool 클래스의 문서.

문제:

  • 처리는 fork()를 사용하므로 Win32에서는 주의해야 합니다.
  • 프로세스 간에 전송되는 객체는 피클 가능해야 합니다.
  • 작업자가 상대적으로 빠른 경우 청크 크기를 조정할 수 있습니다.일괄적으로 작업자 프로세스에 전송되는 작업 항목 수
  • 처리.풀은 백그라운드 스레드를 사용합니다.

Google의 알고리즘을 구현할 수 있습니다. 맵리듀스 물리적으로 별도의 기계를 보유하지 않고.이러한 각 "기계"는 "스레드"라고 생각하십시오. 스레드는 멀티 코어 머신에 자동으로 배포됩니다.

이를 지원하는 컴파일러로 작업하는 경우 다음을 살펴보는 것이 좋습니다. http://www.openmp.org 특정 루프가 병렬화되는 방식으로 코드에 주석을 달 수 있습니다.

또한 훨씬 더 많은 일을 하며 매우 도움이 될 수 있습니다.

예를 들어, 그들의 웹 페이지에서는 gcc4.2가 openmp를 지원할 것이라고 보고합니다.

Java에서도 동일한 스레드 풀이 사용됩니다.그러나 스레드 풀의 스레드는 직렬화 가능하며 다른 컴퓨터로 전송되고 실행을 위해 역직렬화됩니다.

단일 서버에서 멀티 스레드/멀티 코어 사용을 위한 MapReduce 라이브러리를 개발했습니다.모든 것은 라이브러리에 의해 처리되며 사용자는 Map 및 Reduce를 구현하기만 하면 됩니다.Boost 라이브러리로 위치하지만 아직 공식 lib로 허용되지는 않습니다.확인해 보세요 http://www.craighenderson.co.uk/mapreduce

다음 코드를 검토하는 데 관심이 있을 수 있습니다. libdispatch, 이는 Apple의 Grand Central Dispatch의 오픈 소스 구현입니다.

Intel의 TBB 또는 Boost::mpi도 관심을 가질 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top