2014-04-04 2 views
3

우리의 ASIC에는 두 개의 프로세서가 있습니다. 이것은 두 가지 다른 컴파일러가 약간 다르게 작동한다는 것을 의미합니다. 우리는 통신을 위해 둘 사이에 데이터로 가득 찬 구조체를 전달합니다. 이것은 매우 자주 초당 발생하기 때문에 여기에서 구울 시간이별로 없습니다.멀티 프로세서 데이터 통신을위한 구조 패킹

문제는 두 컴파일러 모두 패딩을 다르게 처리한다는 것입니다. 따라서 한 도메인에서 다른 도메인으로 데이터를 복사 할 때 올바르게 정렬되지 않은 값을 얻습니다. 초기 솔루션은 속성 ((포장 된))을 구조 내부의 모든 것에 넣는 것이 었습니다. 이것이 대부분의 시간 동안 작동하는 것처럼 보이지만 결코 이식성이 없습니다. 코드를 다른 플랫폼으로 옮기고 있기 때문에 모든 컴파일러가 속성 ((packed))을 이해하고있는 것은 아니며 코드를 이식성있게 유지하고 싶습니다.

이 문제를 다루는 사람이 있습니까? 무엇을 추천하나요?

미리 감사드립니다.

+0

'#pragma pack'? – alk

+1

endianess도 잊지 마세요. 패킹의 아이디어는 이식 가능해야하지만, * 구문 *은 덜 복잡 할 수 있습니다. –

답변

2

C의 기본 구조 배열 휴대용이 아니므로 __attribute__((packed)) 또는 이와 비슷한 것이 일반적으로 구조체에 고정 레이아웃을 적용하는 일반적인 방법입니다.

다른 옵션은 pad 필드를 적절한 위치에 수동으로 추가하고 두 플랫폼에서 두 구조가 일치하는지 확인하기 위해 각 플랫폼의 정렬 제약 조건을 알아야합니다. 그러나 이것은 본질적으로 수동 attribute((packed))입니다. 드워프 (announcement, paper)에서 pahole 유틸리티가 컴파일러를 가정, 구조의 정렬을 확인하고 볼 수있는 훌륭한 도구입니다

참고 ELF 파일을 방출한다.

+0

파홀에 대한 제안 주셔서 감사합니다, 나는 결코 그런 것을 스스로 발견하지 못했을 것입니다. 내 엘프 파일의 출력을 구문 분석하고 정렬이 일관성이 있는지 확인하는 스크립트를 작성할 것입니다. –

3

필자는 현재 또는 미래의 컴파일러에서 패딩 문제가 발생하지 않도록 이러한 구조를 수동으로 패킹 할 것입니다.

지루하지만 휴대용 미래 보장형 솔루션으로 그만한 가치가 있습니다.

0

데이터 프로토콜에 구조체를 사용하지 않아야하는 이유가 여기에 있습니다. 말하기가 가혹한 것처럼 보일지도 모르지만 구조체는 불행하게도 이식 가능하지 않으므로 위험합니다. 이는 구조체에 복사 원시 데이터를 유사한 압축을 풀고() 함수를 만들 다음

typedef struct 
{ 
    uint32_t x; 
    uint16_t y; 
    ... 
} my_struct_t; // some custom struct 

#define PROTOCOL_SIZE (sizeof(uint32_t) + sizeof(uint16_t) + ...) 


void pack (uint8_t raw_data[PROTOCOL_SIZE], 
      const my_struct_t* ms) 
{ 
    uint16_t i=0; 

    memcpy(&raw_data[i], ms->x, sizeof(ms->x)); 
    i += sizeof(ms->x); 

    memcpy(&raw_data[i], ms->y, sizeof(ms->y)); 
    i += sizeof(ms->y); 

    ... 
} 

을 그리고 :이 (의사 코드) 같은 일을 고려할 수 있습니다.

이점 : 100 % 휴대용. 그리고 프로토콜이 특정 endianess를 지정하면이 함수는 해당 변환을 처리 할 수 ​​있습니다 (아무튼해야합니다).

단점은 추가 메모리 버퍼와 여분의 데이터 복사입니다.

관련 문제