2012-06-19 5 views
2

정보 블록이 포함 된 이진 파일이 있습니다 (이후 패킷으로 참조 할 것입니다.). 각 패킷은 고정 길이 헤더와 가변 길이 본문으로 구성됩니다. 패킷 헤더 자체에서 몸체의 1/10을 결정했습니다. 내 임무는 파일에서 이러한 패킷을 읽고 그들에 대한 몇 가지 작업을 수행하는 것입니다. 다음과 같이 현재 나는이 작업을 수행하고 있습니다 :Java - 병렬로 이진 파일 읽기

  • 랜덤 액세스 파일로 파일을 열면 특정 시작 위치 (사용자가 지정한 시작 위치)로 이동. 이 위치에서 첫 번째 패킷을 읽습니다. 내가 파일 마커의 끝을 칠 때까지 내 작업 을 수행하는 다음 패킷
  • 을 읽는 루프
    • 에 그런 다음 특정 동작을
    • 공연이 계속된다. 당신이 추측 수 있듯이 파일 크기가 큰 경우

는 순차적으로 각 패킷을 읽고 그것을 처리하는 것은 시간이 많이 걸리는 일이다. 어떻게 든이 작업 즉 패킷 생성 작업을 병렬 처리하여 일부 차단 대기열에 넣은 다음 병렬 처리하여 각 패킷을 대기열에서 검색하고 작업을 수행하려고합니다.

누군가 이러한 패킷을 어떻게 병렬로 생성 할 수 있습니까?

+0

각 패킷 헤더 파일의 파일에서 첫 번째 이후의 위치는 이전 패킷의 크기에 좌우됩니까? –

+0

@ 테드 :별로. 읽은 바이트의 특정 서명을 기반으로 다음 패킷 헤더의 시작을 감지합니다. 선행 패킷의 끝 부분 이후에 나타나지만 특정 위치에서는 나타나지 않습니다. – Sujay

답변

5

를 사용하는 것 같아요. 파일을 읽는 것은 IO 속도에 의해 제한되므로 CPU에서이를 병렬화 할 필요가 없습니다. 실제로 일반 하드 드라이브는 순차 IO 용으로 설계되었으므로 비 순차적으로 읽으면 실제로 성능이 크게 저하됩니다. 읽는 각 패킷에 대해 해당 개체를 스레드로부터 안전한 큐에 넣어야합니다.

이제 패킷 처리를 병렬화 할 수 있습니다. 여러 스레드를 작성하고 큐에서 패킷을 각각 읽도록하십시오. 각 스레드는 처리를 수행하여 "완료된"대기열에 넣어야합니다.

일단 IO 스레드가 파일에서 읽기를 완료하면 대기열이 비어지면 작업 스레드가 중지되도록 플래그를 설정해야합니다.

+0

+1. – sarnold

+0

@sarnold : 사실 일 수 있습니다. 필자는 SSD 아키텍처에서 충분한 경험을하지 못했습니다. P – tskuzzy

+0

+1 다중 스레드에 의한 읽기를 방해하기 때문에 성능면에서 매우 중요합니다. –

0

나는 알려진 빠른 방법은 당신은 내가 파일을 믿고있어 있기 때문에 하나의 드라이브에있다 파일을 순차적으로 읽어 하나 개의 스레드가 있어야 java.nio.MappedByteBuffer

+0

간단한 메모리 매핑처럼 들립니다. 표준화되지 않은 바이트 경계에 저장된 패킷을 발견하는 데 어떻게 이것을 사용합니까? – sarnold

+0

헤더에 길이가 있으면 최소한 패킷을 건너 뛸 수 있습니다. 그렇지 않은 경우 병렬 스캔을 수행하여 조정하십시오! 현대의 SSD는 연속적인 파일의 병렬 읽기가 순차적 인 읽기보다 훨씬 빠르지 만 확실히 블록을 메모리에 미리로드하고 파일 포인터를 사용하는 것보다 스캔하는 것이 더 빠릅니다. –

3

플래터가있는 디스크 (SSD는 아님)를 사용하는 경우 디스크 암을 밀리 초 지연시켜 디스크를 스 래시하기 때문에 둘 이상의 스레드가 파일을 읽는 것이 아닙니다. SSD가 있다면 다른 이야기와 함께 읽을 수 있습니다.당신은 하나 개의 스레드가 파일에서 데이터를 읽고 패킷을 생성해야한다 대신

후 다음을 수행 : 일부 번호로 초기화 된 공유 세마포어 'A'(에

  • 대기를하는 것입니다 일하여 '최대 버퍼링 된 패킷'카운트)
  • 가 LinkedList의
  • 신호 서로 공유 세마포어 'B'(이 버퍼에서 패킷의 수를 추적하는)
  • 로 패킷을 추가 공유 객체를 잠글

그런 다음 다음과 같은 일을 많은 다른 스레드를 가질 수 있습니다 :

  • 가 공유 객체를 잠금 (처리 할 패킷이 있는지 확인하기 위해)이 'B'세마포어

    • 대기를
    • LinkedList의에 getFirst와()를 수행하고, 로컬 변수
    • 세마포어 신호 'A'버퍼링 된 패킷리스트
    로 다른 패킷을 허용하는 패킷을 저장할

    이렇게하면 패킷을 가능한 한 빨리 (플래터 디스크에서) 한 연속 시퀀스로 스트라이핑하여 패킷을 읽을 수 있으며 폴링없이 즉시 여러 패킷을 처리 할 수 ​​있습니다.

  • +0

    감사합니다. @AnthonyM 님의 제안에 감사드립니다. 나는 너와 이전 답이 같은 방향을 가리킨다 고 생각한다. 즉, 파일을 병렬로 액세스하는 것보다 패킷을 병렬로 처리하는 것이다. – Sujay