2011-11-10 3 views
5

나는 다음과 같은 코드가 있습니다Parallel.ForEach 루프가 성능을 향상시키는 이유는 무엇입니까?

  if (!this.writeDataStore.Exists(mat)) 
      { 
       BlockingCollection<ImageFile> imageFiles = new BlockingCollection<ImageFile>(); 
       Parallel.ForEach(fileGrouping, fi => DecompressAndReadGzFile(fi, imageFiles)); 


       this.PushIntoDb(mat, imageFiles.ToList()); 
      } 

DecompressAndReadGzFile이 방법이 포함되어 같은 클래스의 정적 방법 내가, 예를 압축 해제 및 GZ 파일을 읽고, 그들 중 많은 오전 메소드 이름에 따라 경찰을. ~ 1000으로, 병렬화의 오버 헤드가 이점을 위해 가치가 있습니다. 그러나, 나는 이점을 보지 않고있다. ANTS 성능 프로파일 러를 사용할 때 병렬화가 발생하지 않는 것처럼 정확하게 같은 시간에 실행되고 있음을 알 수 있습니다. 또한 프로세스 탐색기에서 CPU 코어를 확인하고 두 코어에서 수행되는 작업이 있지만 한 코어가 대부분의 작업을 수행하는 것처럼 보입니다. Parallel.ForEach가 압축을 풀고 파일을 병렬로 읽는 것까지는 무엇을 이해하지 못합니까?

업데이트 된 질문 : 파일 목록에서 정보를 읽는 가장 빠른 방법은 무엇입니까?

문제점 간체 :

  1. 에 .gz 파일 (1200)의 큰 목록이있다.
  2. 각 파일에는 "DATA :"가 포함 된 줄이 있으며 위치와 줄 번호는 정적이 아니며 파일마다 다를 수 있습니다. "DATA"
  3. 우리는 후 첫 수를 검색합니다 (단지 단순화하기 위해) 및 (예 : 목록) 초기 질문에

메모리의 개체에 저장, 나는 병렬를 사용했다 .ForEach 루프하지만 CPU가 둘 이상의 핵심에 바인딩 된 것 같지 않았다.

+0

'DecompressAndReadGzFile'에서 동기화가 완료 되었습니까? – SimonC

+0

나는 알고있다. imageFiles.Add에 대한 호출이 있는데, 자동으로 이해할 수있는 잠금을 추가합니다. – Seth

답변

12

스레드가 IO를 기다리는 데 대부분의 시간을 소비하고있을 가능성이 있습니까? 한 번에 여러 파일을 읽으면 단일 작업으로 디스크 스 래시를 만드는 것보다 더 많이 만들 수 있습니다. 순차적으로 읽는 단일 스레드를 사용하여 성능을 향상시킬 수 있지만 CPU 바인딩 압축 해제를 별도의 스레드로 돌릴 가능성은 있습니다 ... 그러나 디스크의 경우 압축 해제를 수행하는 스레드가 실제로 필요합니다. 압축 해제 프로세스 자체보다 느립니다.

이 방법을 테스트하는 한 가지 방법은 압축 해제가 필요한 파일을 먼저 램 디스크에 복사하고 현재 코드를 사용하는 것입니다. 나는 당신이 CPU 기반이라는 사실을 알게 될 것이고, 모든 프로세서는 거의 항상 바쁘다고 생각합니다.

는 (당신은 또한. 당신이 압축을 푼 파일과 함께 무슨 일을하는지 고려해야한다, 그래서 다시는 기본적으로 탈곡 디스크를 기다리고있는 가능성이 있다면 당신은? 디스크로 다시 사람들을 쓰고 있습니다.)

+0

압축 해제 된 파일을 디스크에 쓰려고하지 않습니다. GZipStream을 사용하여 메모리에 압축 파일을 읽고, 위의 코드에서 imageFiles 컬렉션에 넣어야하는 내용을 추출하기 위해 TextREader를 만듭니다. RAM 디스크 제안을 시도해 볼 수도 있습니다. – Seth

+0

@Seth : 램 디스크 제안은 실제로 CPU 바인딩이 아닌 IO 바인딩인지 확인하기위한 것입니다.그렇다면 비용이 "램 디스크에 데이터 복사"단계로 이동하게됩니다. –

+0

몇 년 전에 그 하드 디스크 드라이브 터보 부스터 소프트웨어 드라이버를 기억하십니까? 그들은 메모리의 데이터를 압축 한 다음 압축 된 데이터를 디스크에 기록함으로써 디스크 I/O를보다 빠르게 만들었습니다. – dthorpe

0

정적 메서드가 호출간에 전역 리소스를 공유 할 가능성이 있습니다. 이 경우이 정적 메서드가 순차적으로 호출되고 병렬 이익이 없기 때문에. fileGrouping 클래스 코드를 넣을 수 있습니까?

관련 문제