2010-01-03 8 views
8

두 개의 텍스트 파일에서 데이터를 읽고 다른 파일에 결과를 저장하는 프로그램이 있습니다. 퍼포먼스 히트의 원인이되는 많은 데이터가 읽고 쓰여지므로 읽기와 쓰기 작업을 parallize하고 싶습니다.파일 읽기 및 쓰기를 병렬화하는 방법

필자의 초기 생각은 처음에는 2 개의 스레드를 쓰고, 처음부터는 하나의 스레드에서 읽기/쓰기를하고, 또 다른 스레드는 파일의 중간에서 읽기/쓰기를 사용합니다. 내 파일은 행이 아닌 바이트 (각 행은 다른 데이터 바이트를 가질 수 있음)로 포맷되므로, 바이트 단위로 탐색하면 나를 위해 작동하지 않습니다. 그리고 내가 생각할 수있는 해결책은 getline()을 사용하여 이전 행을 건너 뛰는 것이고 이는 효율적이지 않을 수 있습니다.

파일의 지정된 줄을 찾는 좋은 방법이 있습니까? 또는 파일 읽기 및 쓰기를 시차 화하기위한 다른 아이디어가 있습니까?

환경 : Win32에서, C++, NTFS, 단일 하드 디스크

감사합니다.

-Dbger

+1

파일 시스템은 무엇이며 어떤 하드웨어를 사용합니까? 컨트롤러/디스크가 하나만있는 경우 병렬 I/O를 수행하는 것이 효율적이지 않을 수도 있습니다. – Anycorn

+0

그렇다면 동일한 디스크에서 읽기/쓰기 만 수행하면 디스크 I/O를 병렬화하면 항상 성능 저하가 발생합니다. –

+1

Dbger : 하드 디스크를 사용하는 경우 예. – Mike

답변

18

일반적으로, 당신은 디스크 I/O를 병렬화하고 싶지 않아요. 하드 디스크는 데이터를 얻기 위해 끊임없이 탐색해야하기 때문에 임의 I/O를 좋아하지 않습니다. RAID를 사용하지 않고 일부 솔리드 스테이트 메모리가 아닌 하드 드라이브를 사용한다고 가정하면 I/O를 병렬화하면 심각한 성능 저하가 발생합니다 (그러한 기술을 사용하는 경우에도 여전히 성능을 볼 수 있습니다 무작위 입출력을 많이 할 때 저하).

두 번째 질문에 대답하려면 실제로 파일의 특정 줄을 찾는 좋은 방법이 아닙니다. read 함수를 사용하여 명시 적으로 바이트 오프셋을 찾을 수 있습니다 (사용 방법에 대한 자세한 내용은 this page 참조).

+0

파일 읽기/쓰기에서 디스크 스 캐링 비용은 대부분 멀티 스레딩 환경에서 발생합니다. –

+2

예, 디스크 검색 시간은 일반적으로 멀티 스레드 I/O 환경의 병목 현상입니다. 가능한 경우 I/O 직렬화를 시도해야합니다. – Mike

+0

감사합니다. Mike가 확인한 것은 단일 파일을 읽을 때만 적용되거나 여러 파일을 읽을 때 적용됩니다 (스레드 1이 file1을 읽음, thread2가 파일 2를 읽음). –

1

이것은 실제로 질문에 대한 답변이 아니라 오히려 재 설계입니다 이미 언급했듯이 여러 스레드로 하드 ​​디스크에서 I/O 속도를 높이는 것은 도움이되지 않습니다.

그러나 데이터 감도에 따라 다른 방법을 사용할 수도 있습니다 , 처리량 요구 사항, 데이터 크기 등 데이터의 그림을 유지하는 메모리 구조를 만드는 것은 어렵지 않으며 데이터의 모든 부분에서 텍스트 줄을 쉽고 빠르게 업데이트 할 수 있습니다. 그런 다음 전용 스레드 그 구조와 그 일을 기록하는 것만으로 디스크에 데이터. 데이터를 순차적으로 디스크에 기록하는 것은 매우 빠릅니다. 다른 섹션을 무작위로 찾아서 조각으로 쓰는 것보다 훨씬 빠릅니다.

+0

2M 데이터를 텍스트 파일에 순차적으로 기록하면 컴퓨터에서 약 1 초가 걸리므로 속도가 너무 느립니다. 읽으려면 파일의 메모리 구조를 형성하기 위해 먼저 데이터를 읽어야하며 이는 필자의 요구 사항을 충족 시키기에는 너무 느리다. 그러나 중복 I/O 및 Memorymap 파일에 대한 항목을 조사하여 도움이되는지 확인합니다. –

+1

1 초에 2MB를 씁니까? 그건 놀랍게 느린 것 같습니다. 난 그냥 약 100ms에 파일에 10M을 쓰는 테스트를 실행하고 내 PC는 실제 속도 머신 (3.2GHz와 나는 * 7200rpm 드라이브라고 생각한다)이 아니다. 파일을 열고 쓰는 데 사용하는 API는 무엇입니까? –

+0

루프에서 많은 양의 분리 된 데이터를 저장하기 위해 std :: ofstream을 사용하고 있습니다. "(...) {streamOut << x; streamOut << y}"와 같이, 그리고 듀얼 코어 2.16GHz CPU가있는 7200rpm 드라이브도 있습니다. –

2

하나의 디스크에 대해 여러 개의 읽기 및 쓰기 대기열을 지정하면 도움이되지 않습니다. 응용 프로그램이 CPU에서 많은 작업을 수행했다면 비동기 적으로 읽고 쓰고 디스크 입출력이 백그라운드에서 발생하는 동안 CPU가 작동하게 할 수 있습니다. 또는 두 번째 물리적 하드 드라이브를 얻으십시오 : 하나를 읽고 다른 하나를 씁니다. 알맞게 크기가 조정 된 데이터 세트의 경우 코드를 작성하는 것보다 효과적이고 비용면에서 훨씬 저렴합니다.

+0

CPU가 컴퓨팅으로 바쁠 때 점진적으로 출력 데이터를 쓰려면 백 그라인드 스레드를 사용하십시오. 좋은 생각입니다. 그러나 읽으면서 데이터가 준비되지 않았으므로 많은 작업을 수행 할 수 없습니다. –

+0

Dbger는 데이터의 특성에 따라 다릅니다. 비즈니스에있는 첫 번째 가져 오기 데이터를 처리하는 동안 두 번째 비동기 가져 오기를 처리 대기열에 넣을 수 있다면 디스크가 다른 I/O와 관련이 없으므로 가장 효과적이므로 즉각적인 상황에는 적용 할 수 없습니다. –

관련 문제