2010-01-25 2 views
2

우리는 데이터 행 (총 2 천만 행)에서 약 5 회의 계산이 이루어지는 배치 프로세스를 사용합니다. 당사의 프로덕션 서버에는 적절한 CPU를 갖춘 약 24 개의 프로세서가 있습니다.대량 배치 프로세스에 대한 멀티 스레딩 질문

성능은 우리에게 매우 중요합니다. 우리의 알고리즘이 꽤 효율적이라고 가정 할 때, 최대 시간 성능을 얻는 가장 좋은 방법은 무엇일까요? 특히 멀티 스레드, 스레드 풀 등을 통해 더 나은 성능을 얻을 수 있어야합니까? 또한, Process 객체를 사용하여 배치를 여러 프로그램으로 나눌 수 있습니까?

+0

어떤 종류의 계산을 말하고 있습니까? 곱셈, 무작위 걸음, 검색, 정렬 등을 말하고 있습니까? 또한 5 가지 계산을 원자 단위로 수행합니까? 아니면 이전 연산의 결과에 의존합니까? – hackerhasid

+0

그들은 거의 기본적인 곱셈 등이며, 원자 적입니다. – alchemical

+0

각 행 작업은 어쨌든 현재 행에 의해 영향을받는 다음 행입니까? – zebrabox

답변

4

몇 가지 생각 :

첫째, 당신은 "최고"주위에 좀 더 명확한 둘 필요 - 같은 대규모 처리를 수행에 관련된 장단점이있다. 특히 메모리, I/O 및 CPU 사용률을 고려해야합니다. 각 계산에 필요한 메모리 양. 등등. 당신은 확실히 멀티 몇 가지 방법을 원할 것입니다

  • :

    당신이 컴퓨터에있는 유일한 방법임을 가정 할 때, 당신은 많은 양의 메모리를 가지고 있고, 당신은 처리량을 최적화에 주로 관심이 여기에 몇 가지 제안 사항 스레드 처리.

  • 스레드 풀은 합리적인 방법이지만 I/O 대기 시간이 가장 많은 시간을 소모하지 않도록해야합니다.
  • 계산 결과를 지속하지 않도록 핸드 오프 프로세스를 사용할 수 있습니다. 또한 데이터베이스에 대한 왕복 횟수를 줄이기 위해 결과를 일괄 처리 할 수도 있습니다.
  • 또한 데이터베이스로의 이동을 최소화하기 위해 레코드를 메모리에 일괄 적으로로드하는 것이 좋습니다.
  • 잠금 경합을 줄이려면 가능하면 작업 및 기타 메모리 장벽을 차단하지 마십시오.

스레드 풀에 추가로 이러한 병렬 계산의 개발을 단순화하는 기능을 제공하는 Task Parallel Library도 있습니다. 이것은 코어의 수에 맞게 확장되고 스레드가 사용되는 방식을 최적화하도록 특별히 설계되었습니다. 유용 할 수도있는 Parallel LINQ도 있습니다.

0

스레드 풀은 안전하고 쉬운 방법입니다. 풀에 최대 64 개의 동시 스레드를 사용할 수 있습니다 (실제로는 WaitHandles의 한계 임). Process 객체를 사용하면 디버깅을 둘러싼 새로운 문제점과 복잡성이 생기게됩니다. 특히, 풀에서 제공 할 수있는 병렬 처리에서 얻을 수있는 모든 가치를 고려할 때 트레이드 오프가 가치가있는 것은 아닙니다.

+3

스레드 풀은 WaitForMultipleHandles (64 개로 제한됨) Win32 API에 의해 제한되지 않으며 IO 완료 포트를 기반으로하기 때문에 상당히 높아질 수 있습니다. – Richard

2

전반적으로 .NET 4를 기다릴 수 있다면 PFX (병렬 확장)가 가장 적합한 모델 일 수 있습니다.

그런 다음 많은 프로세스/스레드 시작/종료를 피하십시오. 스레드 풀을 사용하십시오 (프로세스 시작은 매우 비쌉니다. 스레드를 시작하는 것은 매우 비쌉니다).

간단한 접근법 : ~ 50ms 이내에 완료되어야하는 작업으로 계산을 일괄 처리 한 다음 대기열에 넣기 시작하십시오. 어려운 부분은 모든 것이 완료되었음을 보증하는 것입니다. 간단한 완료는 각 작업이 증가 할 때마다 "완료된"카운터를 공유하는 것입니다. 주 스레드는 예상 최종 값에 도달 할 때까지 카운터를 읽으면서 회전합니다.

1

이것은 "5 가지 계산"이 구성하는 것에 많은 영향을줍니다. 이러한 5 가지 계산을 수행하는 데 필요한 중요한 계산이있는 경우 멀티 스레딩이 큰 이점입니다. 작업량이 적 으면 좋은 이익을 얻기 위해 파티셔닝에 더 많은주의를 기울여야합니다.

"각 데이터 행에서"실행되는 경우 가능한 한이 문제를 처리하는 가장 효율적인 방법은 데이터베이스에서 직접 업데이트하는 것입니다. 데이터 클라이언트 측, 처리 및 재 채취를 당기는 것은 DB에서 직접 계산을 시도하는 것보다 훨씬 느립니다. 대부분의 데이터베이스 서버는 독자적으로 스레딩을 지원하며 업데이트 최적화 작업을 잘 수행하므로 DB에서 직접 데이터를 처리 할 수 ​​있다면 최상의 성능을 얻을 수 있습니다.

그럴 수 없다면 Task Parallel Library을 사용하여이 문제를 해결하는 것이 좋습니다. 스레드 풀에 추가 된 작업이 더 나은 전체 처리량을 제공하므로 .NET 4에서 실행하면 특히 유용합니다.

0

세분화 된 평가만으로는 작업을 최적화하는 가장 좋은 방법을 가져올 수 있지만 확실하게 스레드 풀을 사용하면 개선 될 수 있습니다. 가장 일반적인 작업을 찾아 풀에서 나누십시오. 중요한 것은 성능을 측정하는 주요 방법 인 은 병목 현상이 발생한 위치와 개선 할 대상을 알 수 있습니다.

0

가능한 경우 데이터베이스 프로 시저 내에서 이렇게하는 것이 좋습니다. 그렇지 않으면 클라이언트 측 처리가 얼마나 효율적인지는 중요하지 않지만 네트워크를 통해 데이터를 앞뒤로 마샬링함으로써 시간이 지배적 일 수 있습니다. 동일한 머신에서 프로세스를 실행하더라도, (아마도 ODBC) 드라이버를 통해 모든 것을 직렬화해야하는 불이익이 발생할 수 있습니다. 물론 데이터베이스 서버의 주소 공간 (서버가 지원하는 경우) 내에서 실행할 수있는 원시 프로 시저를 작성하지 않는 한.

레코드를 선택하기위한 상한 및 하한을 취한 프로 시저를 작성한 다음 몇 개의 스레드를 포크하고 스레드 당 DB 연결을 할당하는 클라이언트 측 프로그램을 작성한 다음 서버 측 호출을 호출하는 것이 좋습니다. 적절한 크기의 경계 (말하자면 4 백만 행을 갖는 5 개의 쓰레드)를 가진 측 절차. DB 서버가 멀티 스레드라면, 이것은 당신에게 훌륭한 성능을 제공 할 것입니다.

그러나 다중 스레드 접근 방식을 사용하면 많은 행을 업데이트하는 경우 트랜잭션을 충분히 자주 수행하지 않으면 잠금 에스컬레이션 때문에 잠금 문제가 발생할 수 있습니다.

+0

SQL CLR은 어떻습니까? ... 닷넷 코드를 SQL SPROC에 직접 삽입합니다. 번개가 빠를 수도 있습니다 !!! – War

0

SQL Server 2005/2008을 사용하는 경우 CLR 함수로 SQL Server에 계산을 추가하는 것을 고려하십시오. http://msdn.microsoft.com/en-us/library/ms254498%28VS.80%29.aspx. 이것은 T-SQL에서 계산하는 것보다 훨씬 빠르며 데이터를 데이터베이스 안팎으로 이동시키는 비용을 절약 해줍니다. SQL Server는 스레드를 관리합니다. 여러 행을 열어서 성능, 연결 시간 등에 미치는 영향을 측정 할 수 있습니다.