2010-04-07 2 views
6

그래, JPEG로 이미지를 인코딩하기 전에 (다소 최적화되지 않은) 프로그램을 작성했지만, 이제는 MPEG-2 전송 스트림과 그 안에 H.264로 인코딩 된 비디오로 작업하고 있습니다. 이 모든 것을 프로그래밍하기 전에 실제 파일을 처리하는 가장 빠른 방법이 무엇인지 궁금합니다.어느 쪽이 메모리, 정수 또는 문자가 더 빠릅니까? 그리고 파일 매핑이나 청크 읽기?

현재 .mts 파일을 메모리에 파일 매핑하여 작업하고 있지만, 예를 들어 파일을 100MB 씩 메모리로 읽어 들여서 처리하는 것이 더 쉬울 지는 잘 모르겠지만 그런 식으로.

이러한 파일은 플래그를 읽는 데 많은 비트 이동 등이 필요하므로 정수 또는 1 바이트 문자로 한 번에 4 바이트를 읽는 것이 더 빠르면 일부 메모리를 참조 할 때 궁금합니다 . 나는 어딘가에 x86 프로세서가 4 바이트 단위로 최적화되어 있다고 생각했지만 이것이 사실인지 확실하지 않습니다 ...

고마워요!

답변

6

일반적으로 메모리 매핑 된 파일은 파일을 동 기적으로 사용할 수 있어야하는 경우 사용할 수있는 가장 빠른 작업입니다. (O/S가 가끔 약간의 속도 향상을 위해 일을 재정렬 할 수 있도록 해주는 비동기 API가 있지만, 응용 프로그램에서 도움이되지 않는 것 같습니다.)

매핑 된 파일의 주요 이점은 O/S에 의해 디스크에서 여전히 읽혀지는 동안 파일에서 메모리로 작업 할 수 있으며, 자신의 잠금/스레드 파일 읽기 코드를 관리 할 필요가 없습니다.

x86 메모리의 메모리 참조는 실제로 작업하고있는 모든 내용을 한 번에 읽을 수 있습니다. 비 바이트 단위 작업과 관련된 추가 시간은 정수를 바이트 단위로 정렬 할 필요가 없다는 사실을 나타냅니다. 예를 들어, 사물이 4 바이트 경계에 정렬되지 않은 경우 ADD를 수행하는 데 더 많은 시간이 걸리지 만 메모리 복사와 같은 경우에는 약간의 차이가 있습니다. 본질적으로 문자 데이터로 작업하는 경우 모든 것을 정수로 읽고 비트를 시프트하는 것보다이를 유지하는 것이 더 빠를 것입니다.

h.264 또는 MPEG2 인코딩을 수행하는 경우 병목 현상은 디스크 i/o가 아닌 CPU 시간이 될 것입니다.

2

전체 파일에 액세스해야하는 경우 메모리로 읽어 와서 처리하는 것이 더 빠릅니다. 물론 메모리를 낭비하고 파일을 어떻게 든 잠궈 야하므로 일부 다른 응용 프로그램에서는 동시 액세스를 얻을 수 없지만 최적화는 어쨌든 타협에 관한 것입니다. 파일을 건너 뛰는 경우 메모리 매핑이 더 빠릅니다. 파일을 전부 읽을 필요가 없기 때문입니다.

예, 4 바이트 (또는 8 바이트) 단위로 메모리에 액세스하는 것은 바이트 단위로 액세스하는 것보다 빠릅니다. 다시 말하지만, 나중에 데이터를 가지고 무엇을해야하는지에 따라, 그리고 int에서 비트를 만지면 얼마나 숙련 되느냐에 따라 전체적으로 더 빠르지 않을 수도 있습니다. 최적화에 관한 모든 것을에 관해서는

: 메모리에서 읽을 수있는 최적의 크기에 관해서는

  1. 측정
  2. 최적화
  3. 측정
+0

+1, 'meassure, meassure, optimize, meassure again'입니까? –

0

, 나는 당신이 this post를 읽고 즐길 것이라 확신합니다 메모리 액세스 성능 및 캐시 효과에 대해 설명합니다.

1

이들은 순차적 비트 스트림입니다. 기본적으로 임의 액세스없이 한 번에 1 비트 씩 소비합니다.

이 시나리오에서는 읽기를 명시 적으로 버퍼링하는 데 많은 노력을 기울일 필요가 없습니다. 운영 체제가 버퍼링하여 버퍼링합니다. 전에 H.264 파서를 작성했는데, 그 시간은 IO가 아니라 디코딩과 조작에 의해 완전히 지배됩니다.

내 권장 사항은 표준 라이브러리를 사용하고 이러한 비트 스트림을 구문 분석하는 것입니다.

Flavor는 파서이고 사이트에도 MPEG-2 (PS)과 M 부호화기 H.264과 같은 다양한 부품의 예를 포함한다. Flavor는 C++과 같은 언어에서 네이티브 구문 분석 코드를 작성합니다. 메모리 매핑 파일에 대해 고려해야 할

class TargetBackgroundGridDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 7 
{ 
    unsigned int(14) horizontal_size; 
    unsigned int(14) vertical_size; 
    unsigned int(4) aspect_ratio_information; 
} 

class VideoWindowDescriptor extends BaseProgramDescriptor : unsigned int(8) tag = 8 
{ 
    unsigned int(14) horizontal_offset; 
    unsigned int(14) vertical_offset; 
    unsigned int(4) window_priority; 
} 
0

한 가지 가능한 주소 범위보다 큰 크기의 파일이 단지의 일부를 매핑 할 수있을 것입니다 : 여기에 MPEG-2 PS 사양에서 인용입니다 파일. 나머지 파일에 액세스하려면 첫 번째 부분을 매핑 해제하고 다음 부분을 매핑해야합니다.

mpeg 스트림을 디코딩 할 때 비동기 파일 읽기와 함께 이중 버퍼링 방식을 사용할 수 있습니다. 그것은 다음과 같이 작동합니다 :

blocksize = 65536 bytes (or whatever) 
currentblock = new byte [blocksize] 
nextblock = new byte [blocksize] 
read currentblock 
while processing 
    asynchronously read nextblock 
    parse currentblock 
    wait for asynchronous read to complete 
    swap nextblock and currentblock 
endwhile 
관련 문제