애그리 게이터 인 내 프로젝트 중 하나에서 웹에서 피드, 팟 캐스트 등을 구문 분석합니다.
순차 접근 방식을 사용하는 경우 리소스가 많기 때문에 모든 리소스를 처리하는 데 상당한 시간이 걸립니다 (네트워크 문제 및 이와 유사한 문제로 인해).
foreach(feed in feeds)
{
read_from_web(feed)
parse(feed)
}
그래서 동시성을 구현하고 싶고 기본적으로 ThreadPools를 사용하여 작업자 스레드로 처리해야하는지 아니면 TPL에 의존하여 정렬할지 결정할 수 없었습니다.
ThreadPools는 확실히 작업자 스레드로 작업을 처리하고 내가 기대하는 바를 얻을 수 있습니다 (멀티 코어 CPU 환경에서는 다른 코어도 활용됩니다).
그래도 TPL도 추천 방법으로 고려하고 싶지만 조금 걱정이됩니다. 우선 TPL이 ThreadPools를 사용하지만 의사 결정의 추가 계층을 추가한다는 것을 알고 있습니다. 저는 주로 단일 코어 환경이 존재하는 상황에 대해 걱정합니다. 내가 틀리지 않았다면 TPL은 처음에 사용 가능한 CPU 코어 수와 동일한 작업자 스레드 수로 시작됩니다. TPL이 내 IO 바인딩 사례에 대해 순차적 접근 방식과 유사한 결과를 생성하는 것이 두렵습니다.
따라서 IO 바인딩 작업 (내 경우에는 웹에서 리소스 읽기)의 경우 ThreadPools를 사용하고 사물을 제어하는 것이 가장 좋을까요, 아니면 TPL에 의존하는 것이 더 좋을까요? IO 바인딩 시나리오에서도 TPL을 사용할 수 있습니까?
업데이트 : 내 주요 관심사는 단일 코어 CPU 환경에서 TPL이 순차적 접근 방식처럼 작동합니까 아니면 여전히 동시성을 제공합니까? 나는 이미 Parallel Programming with Microsoft .NET을 읽고 있으므로 책을 읽었 지만 이에 대한 정확한 답을 찾을 수 없었습니다.
참고 : 이것은 이전 질문을 다시 표현한 것입니다 [ 스레드 동시성과 병렬성을 함께 사용할 수 있습니까? ] 꽤 잘못된 표현이었습니다.
답변
그래서 나는 대신 이것에 대한 테스트를 작성하고 실제 데이터에서보기로 결정했습니다.
테스트 범례
- Itr : 반복
- Seq : 순차적 접근.
- PrlEx : 병렬 확장-Parallel.ForEach
- TPL : 작업 병렬 라이브러리
- TPool : ThreadPool
시험 결과
싱글 코어 CPU [Win7-32]-VMWare에서 실행-
Test Environment: 1 physical cpus, 1 cores, 1 logical cpus.
Will be parsing a total of 10 feeds.
________________________________________________________________________________
Itr. Seq. PrlEx TPL TPool
________________________________________________________________________________
#1 10.82s 04.05s 02.69s 02.60s
#2 07.48s 03.18s 03.17s 02.91s
#3 07.66s 03.21s 01.90s 01.68s
#4 07.43s 01.65s 01.70s 01.76s
#5 07.81s 02.20s 01.75s 01.71s
#6 07.67s 03.25s 01.97s 01.63s
#7 08.14s 01.77s 01.72s 02.66s
#8 08.04s 03.01s 02.03s 01.75s
#9 08.80s 01.71s 01.67s 01.75s
#10 10.19s 02.23s 01.62s 01.74s
________________________________________________________________________________
Avg. 08.40s 02.63s 02.02s 02.02s
________________________________________________________________________________
싱글 코어 CPU [WinXP]-VMWare에서 실행-
Test Environment: 1 physical cpus, NotSupported cores, NotSupported logical cpus.
Will be parsing a total of 10 feeds.
________________________________________________________________________________
Itr. Seq. PrlEx TPL TPool
________________________________________________________________________________
#1 10.79s 04.05s 02.75s 02.13s
#2 07.53s 02.84s 02.08s 02.07s
#3 07.79s 03.74s 02.04s 02.07s
#4 08.28s 02.88s 02.73s 03.43s
#5 07.55s 02.59s 03.99s 03.19s
#6 07.50s 02.90s 02.83s 02.29s
#7 07.80s 04.32s 02.78s 02.67s
#8 07.65s 03.10s 02.07s 02.53s
#9 10.70s 02.61s 02.04s 02.10s
#10 08.98s 02.88s 02.09s 02.16s
________________________________________________________________________________
Avg. 08.46s 03.19s 02.54s 02.46s
________________________________________________________________________________
듀얼 코어 CPU [Win7-64]
Test Environment: 1 physical cpus, 2 cores, 2 logical cpus.
Will be parsing a total of 10 feeds.
________________________________________________________________________________
Itr. Seq. PrlEx TPL TPool
________________________________________________________________________________
#1 07.09s 02.28s 02.64s 01.79s
#2 06.04s 02.53s 01.96s 01.94s
#3 05.84s 02.18s 02.08s 02.34s
#4 06.00s 01.43s 01.69s 01.43s
#5 05.74s 01.61s 01.36s 01.49s
#6 05.92s 01.59s 01.73s 01.50s
#7 06.09s 01.44s 02.14s 02.37s
#8 06.37s 01.34s 01.46s 01.36s
#9 06.57s 01.30s 01.58s 01.67s
#10 06.06s 01.95s 02.88s 01.62s
________________________________________________________________________________
Avg. 06.17s 01.76s 01.95s 01.75s
________________________________________________________________________________
쿼드 코어 CPU [Win7-64]-HyprerThreading 지원-
Test Environment: 1 physical cpus, 4 cores, 8 logical cpus.
Will be parsing a total of 10 feeds.
________________________________________________________________________________
Itr. Seq. PrlEx TPL TPool
________________________________________________________________________________
#1 10.56s 02.03s 01.71s 01.69s
#2 07.42s 01.63s 01.71s 01.69s
#3 11.66s 01.69s 01.73s 01.61s
#4 07.52s 01.77s 01.63s 01.65s
#5 07.69s 02.32s 01.67s 01.62s
#6 07.31s 01.64s 01.53s 02.17s
#7 07.44s 02.56s 02.35s 02.31s
#8 08.36s 01.93s 01.73s 01.66s
#9 07.92s 02.15s 01.72s 01.65s
#10 07.60s 02.14s 01.68s 01.68s
________________________________________________________________________________
Avg. 08.35s 01.99s 01.75s 01.77s
________________________________________________________________________________
요약
- 단일 코어 환경에서 실행하든 멀티 코어 환경에서 실행하든 Parallel Extensions, TPL 및 ThreadPool 은 동일하게 작동하며 대략적인 결과를 제공합니다 .
- 여전히 TPL 에는 쉬운 예외 처리, 취소 지원 및 작업 결과를 쉽게 반환하는 기능과 같은 장점 이 있습니다 . Parallel Extensions도 또 다른 실행 가능한 대안입니다.
스스로 테스트 실행
여기 에서 소스를 다운로드하고 직접 실행할 수 있습니다 . 결과를 게시 할 수 있으면 나도 추가하겠습니다.
업데이트 : 소스 링크를 수정했습니다.
답변
IO 바인딩 작업의 처리량을 최대화하려는 경우 기존 APM (Asynchronous Processing Model) API를 TPL 기반 작업과 결합 해야합니다 . APM API는 비동기 IO 콜백이 보류중인 동안 CPU 스레드의 차단을 해제하는 유일한 방법입니다. TPL은 APM과 TPL 코드를 결합하는 데 도움이 되는 TaskFactory::FromAsync
도우미 메서드 를 제공 합니다 .
이 두 프로그래밍 모델을 결합하여 비동기식 열반을 달성하는 방법에 대한 자세한 내용은 MSDN에서 TPL 및 기존 .NET 비동기 프로그래밍 이라는 제목의 .NET SDK 섹션을 확인하십시오 .
답변
TPL이 자신의 스레드 풀을 만들 때 가지고있는 일부 컨트롤을 제거하는 것은 맞습니다. 그러나 이것은 더 깊이 파고 싶지 않은 경우에만 정확합니다. TPL을 사용하면 TPL 스레드 풀에 속하지 않고 목적에 잘 부합 할 수있는 장기 실행 작업을 만들 수 있습니다. 무료로 읽을 수 있는 Microsoft .NET 을 사용한 병렬 프로그래밍 책인 출판 된 책 은 TPL이 어떻게 사용되는지 훨씬 더 많은 통찰력을 제공합니다. Paralle.For, Tasks에
할당해야하는 스레드 수를 명시 적으로 매개 변수로 지정하는 옵션이 항상 있습니다. 이 외에도 모든 권한을 원하는 경우 TPL 스케줄러를 자신의 스케줄러로 바꿀 수 있습니다.
답변
답변
TPL이 내 IO 바인딩 사례에 대해 순차적 접근 방식과 유사한 결과를 생성하는 것이 두렵습니다.
그럴 것이라고 생각합니다. 병목 현상은 무엇입니까? 파싱 또는 다운로드 중입니까? 멀티 스레딩은 웹에서 다운로드하는 데 큰 도움이되지 않습니다.
작업 병렬 라이브러리를 사용하여 자르기, 다운로드 한 이미지에 마스크 또는 효과 적용, 팟 캐스트에서 일부 샘플 자르기 등을 수행합니다. 확장 성이 더 뛰어납니다.
그러나 그것은 속도 향상 정도가 아닙니다. 일부 기능을 구현하고 테스트하는 데 리소스를 투자하십시오.
추신. “Wow my function execustes in 0.7 s instead of 0.9”;)
답변
URL에 대한 호출을 병렬화하면 코어가 하나만 있어도 애플리케이션이 향상 될 것이라고 생각합니다. 이 코드를 살펴보십시오.
var client = new HttpClient();
var urls = new[]{"a", "url", "to", "find"};
// due to the EAP pattern, this will run in parallel.
var tasks = urls.Select(c=> client.GetAsync(c));
var result = Tasks.WhenAll(task).ContinueWith(a=> AnalyzeThisWords(a.Result));
result.Wait(); // don't know if this is needed or it's correct to call wait
이 경우 멀티 스레딩과 비 동시성의 차이점은 콜백 / 완료가 수행되는 방식입니다.
EAP를 사용할 때 작업 수는 스레드 수와 관련이 없습니다.
GetAsync 작업에 의존하고 있으므로 http 클라이언트는 네트워크 스트림 (소켓, tcp 클라이언트 등)을 사용하고 BeginRead / EndRead가 완료되면 이벤트를 발생 시키도록 신호를 보냅니다. 따라서이 순간에는 스레드가 없습니다.
완료가 호출 된 후 새 스레드가 생성 될 수 있지만 새 스레드를 생성하거나 기존 스레드를 사용하거나 작업을 인라인하여 호출 스레드를 사용하는 것은 TaskScheduler (GetAsync / ContinueWith 호출 호출에 사용됨)에 달려 있습니다.
경우 AnalyzeThisWords
너무 많은 시간 블록, 당신은 스레드 풀 노동자에서 수행하는 ContinueWith에서 “콜백”로 병목 현상을 얻을 시작합니다.
답변
