C에서 바이너리 파일을 구문 분석하는 성능적이고 깨끗한 방법은 무엇입니까?

CSStudent7782

형식을 알고있는 사용자 지정 이진 파일 구조를 구문 분석하고 있습니다.

일반적인 아이디어는 각 파일이 순차적 인 바이트 블록으로 나뉘어 병렬로 분리 및 디코딩하려는 것입니다.

읽을 수 있고 성능이 좋은 대안을 찾고 있습니다. decode_block()

현재 작업중인 작업은 다음과 같습니다.

#include <stdio.h>

int decode_block(uint8_t buffer[]);

int main(){
  FILE *ptr;

  ptr = fopen("example_file.bin", "rb");
  if (!ptr){
    printf("can't open.\n");
    return 1;
  }

  int block1_size = 2404;
  uint8_t block1_buffer[block1_size];
  fread(block1_buffer, sizeof(char), block1_size, ptr);

  int block2_size = 3422;
  uint8_t block2_buffer[block2_size];
  fread(block2_buffer, sizeof(char), block2_size, ptr);

  fclose(ptr);

  //Do these in parallel
  decode_block(block1_buffer);
  decode_block(block2_buffer);
  return 0;
}

int decode_block(uint8_t buffer[]){
  unsigned int size_of_block = (buffer[3] << 24) + (buffer[2] << 16) + (buffer[1] << 8) + buffer[0];
  unsigned int format_version = buffer[4];
  unsigned int number_of_values = (buffer[8] << 24) + (buffer[7] << 16) + (buffer[6] << 8) + buffer[5];
  unsigned int first_value = (buffer[10] << 8) + buffer[9];

  // On and on and on

  int ptr = first_value
  int values[number_of_values];

  for(int i = 0; i < number_of_values; i++){
    values[i] = (buffer[ptr + 3] << 24) + (buffer[ptr + 2] << 16) + (buffer[ptr + 1] << 8) + buffer[ptr];
    ptr += 4
  }

  // On and on and on

  return 0
}

전체 파일을 바이트 배열로 읽은 다음 배열을 바이트 단위로 해석하는 것은 약간 중복 된 느낌입니다. 또한 매우 부피가 큰 코드를 만듭니다.

그러나 파일의 여러 부분을 병렬로 작업해야하므로 다른 방법을 생각할 수 없습니다. 또한 초기 바이트를 buffer존경받는 메타 데이터 값으로 변환하는 더 간단하거나 빠른 방법이 있습니까?

Brendan

신분증:

  • 원시 데이터를로드하지 않으려면 "메모리 매핑 파일"을 사용하십시오 (예 : mmap()POSIX 시스템). 이것은 이식 가능한 "일반 C"가 아니지만 거의 모든 OS가이를 수행하는 방법을 지원합니다.

  • 파일 형식 사양에서 값이 파일의 4 바이트 경계에 정렬되어야하며 (실제로 부호있는 정수를 지원해야하는 경우) 값이 "부호가 아닌"2의 보완 "형식으로 저장되어야합니다. 및 규모 "또는 기타)

  • 파일이 가능한 한 사양을 준수하는지 확인하십시오 (정렬 요구 사항뿐만 아니라 "데이터는 헤더 중간에서 시작할 수 없습니다", "데이터 시작 + 항목 * entry_size는 파일 크기를 초과 할 수 없음"과 같은 항목을 포함하여, "인식되지 않는 버전"등).

  • #ifdef메모리 매핑 파일의 데이터를 int32_t(또는 uint32_t)로 캐스팅 할 수있는 리틀 엔디안 머신 (예 : 컴파일 타임에 사용되는 코드를 선택할 수있는 위치)에 대해 다른 코드를 사용 합니다. 표시 한 코드 (예 : (buffer[ptr + 3] << 24) + (buffer[ptr + 2] << 16) + (buffer[ptr + 1] << 8) + buffer[ptr])"2의 칭찬"컴퓨터에서도 음수로 구분됨)에 유의하십시오. 따라서 대체 코드 ( "리틀 엔디안이 아님"의 경우)는 귀하의 코드보다 더 복잡하고 느립니다. 물론 음수를 지원할 필요가 없다면 부호있는 정수 유형 (예 int:)을 사용해서는 안되며, 솔직히 int32 비트 값에 "아마도 16 비트" 사용해서는 안됩니다 .

  • 사용할 스레드 수를 결정합니다 (명령 줄 인수 일 수 있습니다. 컴퓨터에 실제로있는 CPU 수를 OS에 물어볼 수도 있음). 스레드를 시작하고 어떤 "스레드 번호"인지 알려주십시오 (기존 스레드는 0 번, 처음 생성 된 스레드는 1 번 등).

  • 스레드가 "스레드 번호", 전역 "총 스레드", 전역 "총 항목"및 전역 "첫 항목 오프셋"에서 시작 및 끝 오프셋 (메모리 매핑 파일에서)을 계산하도록합니다. 이것은 대부분 반올림에 특별한주의를 기울인 분할입니다. (전역 변수를 피하기 위해) 대신 각 스레드에 세부 정보가 포함 된 구조를 전달할 수 있습니다. 스레드는 데이터를 읽기만하기 때문에이 데이터에 대한 보호 장치 (예 : 잠금, 중요 섹션)가 필요하지 않습니다.

  • 각 스레드가 데이터 섹션을 병렬로 구문 분석하도록합니다. 그런 다음 모두 완료 될 때까지 기다립니다 (예 : 나중에 사용하기 위해 스레드를 유지하지 않으려면 "thread number 0"이 "pthread_join ()"을 수행함).

모든 값 (모든 스레드에 의해 구문 분석 됨)이 허용 된 범위 내에 있는지 (파일 형식 사양을 준수하기 위해) 확인해야 할 수도 있습니다. 그렇지 않은 경우 (예 : 파일이 손상되었거나 악의적으로 변조 된 경우)에 대해 일종의 오류 처리 기능이 있습니다. 이것은 (전역 적으로 원자 적으로 증가 된) "지금까지 발견 된 이상한 값의 수"카운터처럼 간단 할 수 있습니다. 모든 값이 구문 분석 된 후 "N dodgy values ​​found"오류 메시지를 표시 할 수 있습니다.

참고 1 : 메모리 매핑 파일을 사용하지 않으려는 경우 (또는 사용할 수없는 경우) 하나의 "파일 판독기 스레드"와 여러 "파일 파서 스레드"를 가질 수 있습니다. 이는 훨씬 더 많은 동기화를 필요로합니다 (흐름 제어 기능이있는 FIFO 대기열로 넘어갑니다. 예를 들어 공급자 스레드가 "대기열이 가득 차는 동안 {대기}"를 수행하고 소비자 스레드가 "대기열이 비어있을 때 {대기}"를 수행하는 경우)). 이 추가 동기화는 메모리 매핑 된 파일을 사용하는 것에 비해 오버 헤드를 증가시키고 더 느리게 만듭니다 (더 복잡 할뿐만 아니라).

참고 2 : 파일의 데이터가 운영 체제의 파일 데이터 캐시에 의해 캐시되지 않는 경우 수행하는 작업에 관계없이 파일 IO에 의해 병목 현상이 발생할 수 있으며 여러 스레드를 사용하는 것이이 경우 성능에 도움이되지 않을 것입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

파이썬에서 Lucene 쿼리를 구문 분석하는 적절한 방법은 무엇입니까?

분류에서Dev

파이썬에서 Lucene 쿼리를 구문 분석하는 적절한 방법은 무엇입니까?

분류에서Dev

파이썬에서 regexp로이 텍스트 파일을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

파이썬에서 큰 XML 파일을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

파이썬에서 객체 구조적 유사성을 찾는 깨끗하고 효율적인 방법은 무엇입니까?

분류에서Dev

파일에서 한 줄을 읽고 구문 분석하는 방법은 무엇입니까?

분류에서Dev

Git 속성에서 파일을 바이너리로 표시하는 적절한 방법은 무엇입니까?

분류에서Dev

iPhone에서 CSV 파일을 테이블보기로 구문 분석하는 방법은 무엇입니까?

분류에서Dev

동일한 애플리케이션에서 GCM을 구현하고 알림을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

iOS에서 이러한 유형의 JSON 응답을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

Java에서 이러한 유형의 JSON을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

Java에서 이러한 유형의 JSON을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

각 행에 여러 열이있는 CSV 파일을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

구성 파일을 임시로 바꾸는 깨끗한 방법?

분류에서Dev

파이썬에서 여러 줄 문자열을 작성하는 깨끗한 방법이 있습니까?

분류에서Dev

파이썬에서 JSON 문자열을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

자동 닫는 태그 사이의 텍스트에 대한 .trs XML 파일을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

Laravel 5 뷰에서 벤더 파일에 액세스하는 쉽고 깨끗한 방법은 무엇입니까?

분류에서Dev

파이썬에서 조건문을 작성하는 더 깨끗한 방법

분류에서Dev

Python / OpenCV에서 이미지를 깨끗한 단락으로 분할하는 방법은 무엇입니까?

분류에서Dev

자바 :이 상황에서 문자열을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

바이너리 파일을 C / C ++ 문자열 리터럴로 덤프하는 방법은 무엇입니까?

분류에서Dev

Java에서 기간을 구문 분석하는 가장 깨끗한 방법

분류에서Dev

웹 서버 로그 파일에서 데이터를 추출하고 요청 줄 부분을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

파이썬에서 xml을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

파이썬 목록에 쉼표없이 문자열을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

sdcard에서 여러 파일을 구문 분석하고 수신 된 데이터를 데이터베이스에 삽입하는 방법은 무엇입니까?

분류에서Dev

데이터가 객체가 아닌 문자열 일 때 Android에서 동일한 json 응답을 구문 분석하는 방법은 무엇입니까?

분류에서Dev

Perl Regex : \ "없이"에서 "까지 문자열을 구문 분석하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    파이썬에서 Lucene 쿼리를 구문 분석하는 적절한 방법은 무엇입니까?

  2. 2

    파이썬에서 Lucene 쿼리를 구문 분석하는 적절한 방법은 무엇입니까?

  3. 3

    파이썬에서 regexp로이 텍스트 파일을 구문 분석하는 방법은 무엇입니까?

  4. 4

    파이썬에서 큰 XML 파일을 구문 분석하는 방법은 무엇입니까?

  5. 5

    파이썬에서 객체 구조적 유사성을 찾는 깨끗하고 효율적인 방법은 무엇입니까?

  6. 6

    파일에서 한 줄을 읽고 구문 분석하는 방법은 무엇입니까?

  7. 7

    Git 속성에서 파일을 바이너리로 표시하는 적절한 방법은 무엇입니까?

  8. 8

    iPhone에서 CSV 파일을 테이블보기로 구문 분석하는 방법은 무엇입니까?

  9. 9

    동일한 애플리케이션에서 GCM을 구현하고 알림을 구문 분석하는 방법은 무엇입니까?

  10. 10

    iOS에서 이러한 유형의 JSON 응답을 구문 분석하는 방법은 무엇입니까?

  11. 11

    Java에서 이러한 유형의 JSON을 구문 분석하는 방법은 무엇입니까?

  12. 12

    Java에서 이러한 유형의 JSON을 구문 분석하는 방법은 무엇입니까?

  13. 13

    각 행에 여러 열이있는 CSV 파일을 구문 분석하는 방법은 무엇입니까?

  14. 14

    구성 파일을 임시로 바꾸는 깨끗한 방법?

  15. 15

    파이썬에서 여러 줄 문자열을 작성하는 깨끗한 방법이 있습니까?

  16. 16

    파이썬에서 JSON 문자열을 구문 분석하는 방법은 무엇입니까?

  17. 17

    자동 닫는 태그 사이의 텍스트에 대한 .trs XML 파일을 구문 분석하는 방법은 무엇입니까?

  18. 18

    Laravel 5 뷰에서 벤더 파일에 액세스하는 쉽고 깨끗한 방법은 무엇입니까?

  19. 19

    파이썬에서 조건문을 작성하는 더 깨끗한 방법

  20. 20

    Python / OpenCV에서 이미지를 깨끗한 단락으로 분할하는 방법은 무엇입니까?

  21. 21

    자바 :이 상황에서 문자열을 구문 분석하는 방법은 무엇입니까?

  22. 22

    바이너리 파일을 C / C ++ 문자열 리터럴로 덤프하는 방법은 무엇입니까?

  23. 23

    Java에서 기간을 구문 분석하는 가장 깨끗한 방법

  24. 24

    웹 서버 로그 파일에서 데이터를 추출하고 요청 줄 부분을 구문 분석하는 방법은 무엇입니까?

  25. 25

    파이썬에서 xml을 구문 분석하는 방법은 무엇입니까?

  26. 26

    파이썬 목록에 쉼표없이 문자열을 구문 분석하는 방법은 무엇입니까?

  27. 27

    sdcard에서 여러 파일을 구문 분석하고 수신 된 데이터를 데이터베이스에 삽입하는 방법은 무엇입니까?

  28. 28

    데이터가 객체가 아닌 문자열 일 때 Android에서 동일한 json 응답을 구문 분석하는 방법은 무엇입니까?

  29. 29

    Perl Regex : \ "없이"에서 "까지 문자열을 구문 분석하는 방법은 무엇입니까?

뜨겁다태그

보관