2017-09-08 6 views
0

필자는 각각 64 비트 길이의 8 비트 벡터를 포함하는 데이터 구조를 가지고 있습니다. 그러나 이러한 배열의 개별 바이트는 하나씩 이어지는 대신 데이터 구조 전체에 인터리브됩니다. 주어진 비트 벡터의 각 연속 바이트는 이전 바이트보다 8 바이트 뒤에 있습니다. 현대의 x86-64 CPU에서 이러한 인터리브 어레이와 64 비트 워드간에 데이터를 이동하는 효율적인 방법 (예 : 병렬로드 및 저장)이 있습니까? 임베디드 ASM이있는 C 코드는 gcc 내장 함수를 사용하는 솔루션이 더 좋을지라도 괜찮습니다.인터리브 된 배열을 읽거나 쓰는 방법은 무엇입니까?

+3

달성하기위한 몇 가지 흥미로운 기술이있을 수 있습니다. 일부 샘플 데이터와 달성하려는 결과의 최적화되지 않은 버전을 포함하여 누군가가 당신을 도울 수 있도록 구조의 가능한 실행 가능한 예를 게시하십시오. 그것이 그대로, 그것은 구체적인 것을 모른 채로 매우 광범위한 질문입니다. –

+1

이 작업을 수행하는 영리한 방법이있을 수 있지만 (VPSHUFB는 마음에 들었습니다.) 많은 양의 데이터를 처리하지 않는 한 작성하고 테스트하는 시간과 노력이 많이 절약되지는 않습니다. SBS의 솔루션은 AVX2 또는 AVX512BW를 사용하여 asm으로 작성된 것만 큼 섹시하지 않을 수 있지만 훨씬 더 이식 가능하고 유지 관리가 가능할 것입니다. 이것이 코드에서 성능 병목 현상이 아니라면, 나는 섹시 함으로 간단하게 투표 할 것입니다. –

답변

0

저는 인터리브 된 데이터에서 작동하는 x64 CPU 명령어를 알지 못합니다. 그 CPU가에 꽤 빠르다 때문에, 이동 및 I/O를, 나는 8 다음과 같은 방법을 사용할 것 색인은 /는 복사 작업으로 이동하고, 최적화에 남은 작업을 남겨 인라인 :

void Write (unsigned char*  bytes, 
      unsigned long long value, 
      int    offset) 
    { 
    bytes [offset  ] = (unsigned char) (value  ); 
    bytes [offset + 8] = (unsigned char) (value >> 8); 
    bytes [offset + 16] = (unsigned char) (value >> 16); 
    bytes [offset + 24] = (unsigned char) (value >> 24); 
    bytes [offset + 32] = (unsigned char) (value >> 32); 
    bytes [offset + 40] = (unsigned char) (value >> 40); 
    bytes [offset + 48] = (unsigned char) (value >> 48); 
    bytes [offset + 56] = (unsigned char) (value >> 56); 
    return; 
    } 

void Read (unsigned char*  bytes, 
      unsigned long long* value, 
      int     offset) 
    { 
    *value = ((unsigned long long) bytes [offset  ]  ) | 
      ((unsigned long long) bytes [offset + 8] << 8) | 
      ((unsigned long long) bytes [offset + 16] << 16) | 
      ((unsigned long long) bytes [offset + 24] << 24) | 
      ((unsigned long long) bytes [offset + 32] << 32) | 
      ((unsigned long long) bytes [offset + 40] << 40) | 
      ((unsigned long long) bytes [offset + 48] << 48) | 
      ((unsigned long long) bytes [offset + 56] << 56); 
    return; 
    } 

이 코드 저장 리틀 엔디안 순서로 된 64 비트 값 빅 엔디안의 경우 반대 순서로 바이트를 읽고 쓰면됩니다.