2012-05-20 4 views
8

메모리로 8192x8192 행렬을 읽어야합니다. 나는 가능한 한 빨리 그것을하고 싶다. 나는 각 줄을 구문 분석 atoi을하고 행렬을 채우는 함수 ParallelRead에서멀티 스레드 응용 프로그램에서 가장 빠른 파일 읽기

char inputFile[8192][8192*4]; // I know the numbers are at max 3 digits 
int8_t matrix[8192][8192]; // Matrix to be populated 

// Read entire file line by line using fgets 
while (fgets (inputFile[lineNum++], MAXCOLS, fp)); 

//Populate the matrix in parallel, 
for (t = 0; t < NUM_THREADS; t++){ 
    pthread_create(&threads[t], NULL, ParallelRead, (void *)t); 
} 

:
는 지금은이 구조를 가지고있다. 병렬이 더 이상이 문제를 최적화 할 수있는 방법이 있나요

Loading big file (fgets) : 5.79126 
Preprocessing data (Parallel Read) : 4.44083 

소요 라인 현명한 스레드 t 같은 라인이 개 스레드를 가진 두 개의 코어 시스템에서 t, t+ 1 * NUM_THREADS..

구문 분석이다?

+3

아마도 충분한 데이터가 사용 가능 해지면 채우기 스레드를 i/o와 병렬로 시작할 수 있습니다. – vanza

+0

솔직히 말하자면, 여러 스레드에서 동일한 파일을 읽는 중에 * 성능 향상을 얻을 수 있었다는 사실에 조금 놀랐습니다 ... 벤치마킹 할 때 파일이 실제로 디스크에서 읽혀지고 있는지 확인하고 있습니까? 캐시가 아닌가요? – NPE

+0

@aix 예를 들어 2 개의 스레드를 사용했습니다. 나는 전처리 부분을 병렬 처리했다. 이것은 데이터가 메모리로 읽어 들여진 후이다. – sud03r

답변

2

두 개의 작은 입력 버퍼를 할당하는 것이 고려해야 할 한가지가 있습니다 (각각 200 라인이 될 것입니다).

그런 다음 한 스레드가 입력 버퍼에 데이터를 읽도록하십시오. 하나의 입력 버퍼가 꽉 찼 으면 구문 분석을 수행하는 두 번째 스레드로 전달하십시오. 이 두 번째 스레드는 동시 구문 분석을 위해 스레드 풀을 사용할 수 있습니다 (openMP 확인).

스레드에 단독 액세스 권한이 있는지 확인하려면 잠금/뮤텍스를 사용해야합니다.

구문 분석이 파일 읽기와 동시에 이루어지기 때문에 버퍼에 대한 메모리 액세스가 로컬이므로 CPU 캐시에 적합합니다. 이렇게하면 읽기 및 구문 분석 속도가 향상 될 수 있습니다.

fgets가 병목 일 경우 파일을 바이너리로 메모리에 읽을 수도 있습니다. 이렇게하면 읽기 속도가 향상 될 수 있지만 추가 구문 분석이 필요하며 위에서 설명한 최적화를 수행하기가 더 어려워집니다.

2

fread와 같은 것을 사용하여 문자 배열을로드하는 부모 스레드를 사용하여 1 io의 모든 내용을 큰 문자열로로드하십시오.

부모가 문자열을 걸어보고 1 줄을 찾거나 첫 줄이 크기를 기준으로 계산되는 위치를 계산하십시오. 그 라인의 처리를 스레드에 넘깁니다. 다음 줄, 헹굼, 반복, EOF까지. 스레드와 동기화하십시오. 끝난.

1

파일 I/O에서 얻을 수있는 최상의 성능은 메모리 매핑을 통한 것입니다. This is an example. 단일 스레드 설계에서 시작하여 사후로드 프로세싱이 병목 현상으로 판명되면 병행 성을 나타냅니다.

22

이렇게하면 좋지 않습니다. 충분한 코어가 있지만 여전히 하드 디스크가 하나 뿐인 경우 쓰레드가 더 많은 CPU주기를 확보 할 수 있습니다. 따라서 필연적으로 스레드는 파일 데이터 읽기 속도를 향상시킬 수 없습니다.

그들은 실제로 그것을 훨씬 악화시킵니다. 파일에서 데이터를 읽는 것은 파일에 순차적으로 액세스 할 때 가장 빠릅니다. 이는 디스크 드라이브에서 가장 비싼 작업으로 판독기 헤드 탐색 횟수를 최소화합니다. 파일의 여러 부분을 읽는 여러 스레드에 걸쳐 읽기를 분할하면 독자 헤드가 끊임없이 앞뒤로 건너 뛰게됩니다. 매우 처리량에 좋지 않습니다.

개의 스레드 만 사용하여 파일 데이터를 읽습니다. 파일 데이터의 청크가로드되면 스레드를 시작하여 파일 데이터의 일부 계산주기와이를 겹칠 수 있습니다.

은 테스트 효과가 있음을주의하십시오.일반적으로 프로그램을 다시 실행하면 일반적으로 코드를 약간 조정 한 후에 프로그램이 파일 시스템 캐시에서 파일 데이터를 다시 찾을 수 있으므로 디스크에서 읽을 필요가 없습니다. 이것은 매우 빠르며, 메모리 버스 속도, 메모리 대 메모리 복사입니다. 매우 크지 않고 최신 기계가 가지고있는 RAM의 양에 쉽게 맞을 수 있기 때문에 데이터 세트에서 꽤 가능성이 있습니다. 이것은 (일반적으로) 프로덕션 시스템에서 발생하지 않습니다. 따라서 캐시를 지워서 OS에서 수행되는 모든 작업을 현실적인 수치로 처리하십시오.

+2

그는 파일을 병렬로 읽지 않고, 메모리에서 병렬로 int8_t's 문자열로 변환합니다. 거기에 아무 문제가 없습니다. – kratenko

+0

나는 그것이 잘못되었다고 결코 말하지 않았다. 사실 데이터를 읽는 스레드와 그것을 겹칠 것을 권장합니다. –

관련 문제