비트 배열

Bit array

비트 배열(비트 맵, 비트 세트, 비트 문자열 또는 비트 벡터라고도 함)은 비트를 콤팩트하게 저장하는 배열 데이터 구조입니다.단순한 집합 데이터 구조를 구현하는 데 사용할 수 있습니다.비트 어레이는 하드웨어의 비트레벨 병렬화를 이용하여 작업을 신속하게 수행하는 데 효과적입니다.전형적인 비트 어레이는 kw비트를 기억한다.여기서 w는 바이트워드 등의 기억단위의 비트수이고 k는 음이 아닌 정수이다.w가 저장되는 비트수를 분할하지 않으면 내부 플래그멘테이션으로 인해 일부 공간이 낭비됩니다.

정의.

비트 어레이는 일부 도메인(거의 항상 정수 범위)에서 집합 {0, 1)의 값에 매핑된 것입니다.값은 dark/light, absent/present, locked/unlocked, valid/invalid, et cetera로 해석할 수 있습니다.요점은 가능한 값은 2개뿐이므로 1비트에 저장할 수 있다는 것입니다.다른 어레이와 마찬가지로 어레이에 인덱스를 적용하여 단일 비트에 대한 액세스를 관리할 수 있습니다.크기(또는 길이)를 n비트로 가정하면 어레이를 사용하여 도메인의 서브셋(예를 들어 {0, 1, 2, ..., n-1})을 지정할 수 있습니다.여기서 1비트는 세트의 숫자의 존재를 나타내고 0비트는 숫자의 부재를 나타냅니다.이 세트 데이터 구조에서는 n/w 워드의 공간을 사용합니다.여기서 w는 각 머신 워드의 비트 수입니다.(단어의) 최하위 비트 또는 최하위 비트가 최소 인덱스 수를 나타내는지 여부는 대부분 관련이 없지만 (리틀 엔디언 머신에서는) 전자가 선호되는 경향이 있습니다.

기본 조작

대부분의 기계는 메모리 내의 개별 비트를 주소 지정할 수도 없고 단일 비트를 조작하는 명령도 없지만, 워드 내의 각 비트는 비트 연산을 사용하여 선택하여 조작할 수 있습니다.특히:

  • OR을 사용하여 비트를 111010 또는 00000100 = 11101110으로 설정할 수 있습니다.
  • AND를 사용하여 비트를 0으로 설정할 수 있습니다: 11101010 AND 11111101 = 11101000
  • 또한 제로 테스트와 함께 비트가 설정되어 있는지 여부를 확인할 수 있습니다.
    111010 AND 00000001 = 000000 = 0
    111010 AND 00000010 = 00000010 0 0
  • XOR을 사용하여 비트를 반전 또는 전환할 수 있습니다.
    111010 XOR 00000100 = 11101110
    11101110 XOR 00000100 = 111010
  • NOT를 사용하여 모든 비트를 반전할 수 없습니다.
    Not 10110010 = 01001101

이러한 작업에 필요한 비트 마스크를 얻으려면 비트 시프트 연산자를 사용하여 숫자 1을 적절한 자리수만큼 왼쪽으로 이동시키고 필요에 따라 비트 단위로 부정할 수 있습니다.

세트를 나타내는 같은 크기의 2개의 비트어레이를 지정하면, 각각 n/w의 단순한 비트연산(차이의 경우 2n/w)과 다음 중 하나를 사용하여 결합, 교집합 및 설정 이론의 차이를 계산할 수 있습니다.

0 ~ n/w-1 보_a[i] := not a[i] union[i] 또는 b[i] 교차로[i] := a[i] 및 b[i] 차이 [i] := a[i] 및 (b[i]가 아님) 

비트 배열의 비트를 반복하는 경우, 한 번에 하나씩 각 워드를 루프하는 이중 중첩 루프를 사용하여 효율적으로 실행할 수 있습니다.n/w 메모리 액세스만 필요합니다.

i가 0 ~ n/w-1 인덱스 : = 0 // 필요한 경우 단어 : = a[i], b가 0 ~w-1 값 : = 워드 및 1µ 0 워드 시프트 right 1 // 필요한 경우 값 인덱스 : = index + 1 //로 작업을 수행합니다.

이러한 코드 샘플은 모두 이상적인 참조 위치를 나타내며, 이후 데이터 캐시에서 성능이 크게 향상됩니다.캐시 행이 k워드일 경우 약 n/wk 캐시 누락만 발생합니다.

보다 복잡한 운용

문자열과 마찬가지로 길이, 부분 문자열, 사전 비교, 연결, 역연산정의하는 것은 간단합니다.이러한 조작의 일부의 실장은, 엔디안성에 민감합니다.

인구 / 해밍 중량

모집단 카운트 또는 해밍 웨이트라고도 불리는 비트 배열의 1비트 수를 찾으려면 일련의 간단한 비트 연산을 사용하여 워드 내의 비트 수를 계산할 수 있는 효율적인 분기 없는 알고리즘이 있습니다.단어마다 이러한 알고리즘을 실행하여 합계를 유지합니다.0을 세는 것도 비슷합니다.효율적인 구현의 예는 Hamming weight 문서를 참조하십시오.

반전

픽셀당 1비트 이미지의 수직 플립 또는 일부 FFT 알고리즘에서는 개별 워드의 비트를 플립해야 합니다(따라서).b31 b30 ... b0된다b0 ... b30 b31이 조작을 프로세서에서 사용할 수 없는 경우에도 연속 패스로 진행할 수 있습니다(이 예에서는 32비트).

2개의 16비트 하프워드를 쌍(0xdccbaa -> 0xccdaabb)으로 교환하고...스왑 비트를 쌍으로 교환한다(b31 b30 ...b1 b0 -> b30 b31 ...b0 b0 b1 )마지막 조작은 기입할 수 있습니다(x&0x55555) << 1) (x&0xaaaaaa) > > > 1 。 

첫 번째 검색

first set or first one find 조작은 어레이 내에서 가장 작은 인덱스로 1비트의 인덱스 또는 위치를 식별하며 광범위한 하드웨어 지원(워드 이하 어레이용)과 효율적인 계산을 위한 알고리즘을 제공합니다.priority 큐가 비트 배열에 저장되어 있는 경우 첫 번째 priority 큐를 사용하여 큐 내에서 가장 높은 priority 요소를 식별할 수 있습니다.번째 단어 크기 찾기부터 긴 배열까지 확장하려면 첫 번째 0이 아닌 단어를 찾은 다음 해당 단어에서 첫 번째 단어 찾기를 실행합니다.관련된 동작은 첫 번째 제로 검색, 선두 0 카운트, 선두 0 카운트, 후속 0 카운트, 후행 0 카운트, 후행 1 카운트 및 로그베이스 2(첫 번째 세트 검색 참조)도 쉽게 비트 배열로 확장할 수 있습니다.

압축

비트 배열은 "랜덤" 비트의 가장 밀도가 높은 스토리지입니다. 즉, 각 비트가 0 또는 1일 가능성이 높고 각 비트는 독립적입니다.그러나 대부분의 데이터는 랜덤 데이터가 아니기 때문에 더 콤팩트하게 저장할 수 있습니다.예를 들면, 일반적인 팩스 화상의 데이터는 랜덤이 아니고, 압축할 수 있습니다.런렝스 부호화는 일반적으로 이러한 긴 스트림을 압축하기 위해 사용됩니다.그러나 대부분의 압축된 데이터 형식은 랜덤으로 액세스하기가 쉽지 않습니다.또한 비트 어레이를 너무 적극적으로 압축하면 비트 레벨 병렬화(벡터화)로 인한 이점을 잃을 위험이 있습니다.따라서 비트 배열을 비트 스트림으로 압축하는 대신 바이트 또는 워드의 스트림으로 압축할 수 있습니다(비트맵 인덱스(압축) 참조).

장점과 단점

비트 어레이는 단순함에도 불구하고 동일한 문제에 대해 다른 데이터 구조보다 많은 이점이 있습니다.

  • n개의 독립된 데이터를 n/w 워드에 저장할 수 있는 다른 데이터 구조는 없습니다.
  • 이를 통해 메모리 액세스 없이 레지스터 세트에 작은 비트 배열을 장기간 저장하고 조작할 수 있습니다.
  • 비트 레벨의 병렬화를 이용하고, 메모리 액세스를 제한하고, 데이터 캐시를 최대한으로 사용할 수 있기 때문에, 실제 데이터 세트에서는 다른 많은 데이터 구조를 능가하는 경우가 많습니다. 심지어 점근적으로 더 효율적인 데이터 세트에서도 마찬가지입니다.

그러나 비트 어레이가 모든 것을 해결할 수 있는 것은 아닙니다.특히:

  • 압축이 없으면 시간과 공간 모두에서 스파스 집합(범위에 비해 요소가 적은 집합)에 대한 낭비적인 집합 데이터 구조입니다.이러한 응용 프로그램에서는 압축 비트 배열, Judy 배열, 시도 또는 Bloom 필터를 고려해야 합니다.
  • 개별 요소에 액세스하는 것은 비용이 많이 들고 일부 언어로 표현하기 어려울 수 있습니다.랜덤 액세스가 시퀀셜보다 일반적이고 어레이가 비교적 작을 경우 바이트 어드레싱을 가진 머신에서 바이트 어레이가 바람직할 수 있다.단, 워드어드레싱만 장비되어 있지 않으면 공간 오버헤드가 크고 캐시 누락이 늘어나기 때문에 워드어레이가 정당화되지 않을 수 있습니다.

적용들

비트 어레이는 콤팩트하기 때문에 공간이나 효율이 높은 영역에 여러 가지 응용 프로그램이 있습니다.일반적으로 부울 플래그의 단순한 그룹 또는 부울 값의 순서가 지정된 시퀀스를 나타내기 위해 사용됩니다.

비트 배열은 priority 큐에 사용됩니다.여기서 k의 비트는 k가 큐에 있는 경우에만 설정됩니다.예를 들어 Linux 커널에 의해 사용되며 하드웨어에서 find-first-zero 조작을 통해 큰 이점을 얻을 수 있습니다.

비트 어레이메모리 페이지, inode, 디스크 섹터 등의 할당에 사용할 수 있습니다.이 경우 비트맵이라는 용어를 사용할 수 있습니다.단, 이 용어는 픽셀당 여러 비트를 사용할 수 있는 래스터 이미지를 나타낼 때 자주 사용됩니다.

비트 어레이의 또 다른 적용 분야는 Bloom 필터입니다.Bloom 필터는 작은 오류 확률을 대가로 작은 공간에 큰 세트를 저장할 수 있는 확률론적 집합 데이터 구조입니다.false positive 또는 false negative 중 하나를 받아들이는 비트배열을 기반으로 확률론적 해시 테이블을 작성할 수도 있습니다.

비트 배열과 비트 배열에서의 조작은 가능한 최소 공간에 가까운 간결한 데이터 구조를 구축하는 데에도 중요합니다.이 경우 n번째 1비트를 찾거나 특정 위치까지 1비트 수를 카운트하는 등의 조작이 중요합니다.

또한 비트 배열은 압축된 데이터의 스트림을 검사하는 데 유용한 추상화입니다. 압축된 데이터 스트림에는 종종 바이트의 일부를 차지하거나 바이트 정렬되지 않은 요소가 포함됩니다.예를 들어 단일 8비트 문자의 압축된 Huffman 부호화 표현은 1~255비트 길이입니다.

정보 검색에서 비트 배열은 매우 빈번한 용어의 게시 목록을 잘 나타냅니다.엄밀하게 증가하는 정수 목록에서 인접 값 사이의 갭을 계산하고 단항 부호화를 사용하여 부호화하면 n번째 위치에 1비트가 있는 비트 배열이 됩니다.n의 암묵적인 확률은 1/2입니다n.이것은 또한 파라미터 M이 1인 골롬 부호화의 특수한 경우입니다.이 파라미터는 보통 -log(2 - p) / log(1 - p) 1 1일 때만 선택됩니다.또는 대략 38% 이상의 문서에서 용어가 발생합니다.

언어 지원

APL 프로그래밍 언어는 정수와 다른 부울 데이터 유형으로 임의 모양과 크기의 비트 배열을 완전히 지원합니다.모든 주요 구현(Dialog APL, APL2, APL Next, NARS2000, Gnu APL 등)은 기계어 크기에 관계없이 비트를 촘촘히 채웁니다.비트는 통상적인 색인 표기법(A[3])을 통해 개별적으로 액세스 할 수 있을 뿐만 아니라, 통상적인 모든 원시 함수 및 연산자를 통해 액세스 할 수 있습니다.여기서 비트는 바이트의 테이블 룩업을 통해 비트를 합산하는 특수한 케이스 알고리즘을 사용하여 종종 동작합니다.

C 프로그래밍 언어의 비트 필드, 즉 일부 비트 수와 동일한 크기의 구조에서 발견되는 의사 객체는 사실 작은 비트 배열입니다. 단어에 걸쳐질 수 없다는 점에서 제한됩니다.편리한 구문을 제공하지만 대부분의 머신에서 바이트 단위 연산자를 사용하여 비트에 액세스할 수 있으며, 비트는 정적(C의 정적 배열과 마찬가지로 컴파일 시 크기가 고정됨)으로만 정의할 수 있습니다.또한 C 프로그래머는 단어를 작은 비트 배열로 사용하고 비트 연산자를 사용하여 비트에 액세스하는 것이 일반적인 관용어입니다.X11 시스템에 포함된 널리 이용 가능한 헤더 파일인 xtrapbits.h는 "비트의 배열의 비트 필드 조작을 시스템이 정의하는 휴대용 방법"입니다.전술한 접근법에 대한 자세한 설명은 comp.lang.c faq를 참조하십시오.

C++에서는 개별이지만bool는 보통 바이트 또는 정수와 같은 공간을 차지합니다.STL 타입vector<bool>는 공간 효율 최적화로 비트가 패킹되는 부분 템플릿 지정입니다.바이트(비트가 아닌)는 C++에서 주소 지정 가능한 최소 단위이므로 [] 연산자는 요소에 대한 참조를 반환하지 않고 프록시 참조를 반환합니다.사소한 점처럼 보일 수도 있지만, 그 말은vector<bool>표준 STL 컨테이너가 아니기 때문에,vector<bool>일반적으로 권장되지 않습니다.또 하나의 고유한 STL 클래스입니다.bitset[1]컴파일 시 특정 크기로 고정된 비트의 벡터를 만듭니다.인터페이스와 구문은 C 프로그래머가 비트세트로 사용하는 관용적인 단어와 유사합니다.또한 설정된 비트 수를 효율적으로 셀 수 있는 기능 등 약간의 추가 전력도 있습니다.Boost C++ 라이브러리는dynamic_bitset런타임에[2] 크기가 지정된 클래스입니다.

D 프로그래밍 언어는 표준 라이브러리 Phobos에 비트 배열을 제공합니다.std.bitmanipC++에서와 같이 [] 연산자는 참조를 반환하지 않습니다.개개의 비트는 대부분의 하드웨어에서 직접 주소를 지정할 수 없기 때문입니다.대신 a를 반환합니다.bool.

자바에서는 클래스가BitSet는 C 프로그래머에게 익숙한 비트 연산자의 이름을 딴 함수로 조작되는 비트 배열을 만듭니다.와는 달리bitsetC++에서 Java는BitSet에는 '사이즈' 상태가 없습니다(0비트로 초기화되어 있는 실질적으로 무한 크기).비트는 임의의 인덱스로 설정 또는 테스트할 수 있습니다.게다가 수업도 있다.EnumSet비트 필드 대신 비트 벡터로서 내부적으로 열거된 유형의 값 집합을 나타냅니다.

.NET Framework에서는BitArray컬렉션 클래스유형 배열을 사용하여 비트를 저장합니다.int(보통 어레이 내의 각 요소는 32비트를 [3]나타냅니다).클래스는 랜덤액세스 연산자와 비트 연산자를 지원하며 반복할 수 있습니다.Length속성을 변경하여 확장하거나 잘라낼 수 있습니다.

Standard ML은 비트어레이를 지원하지 않지만 New Jersey의 Standard ML은 다음과 같은 확장자를 가지고 있습니다.BitArraySML/NJ 라이브러리에 있습니다.크기는 고정되어 있지 않으며 비정상적으로 시프트 작업을 포함한 세트 작업 및 비트 작업을 지원합니다.

마찬가지로 Haskell은 현재 비트 단위 동작에 대한 표준 지원이 부족하지만 GHC와 Hugs는 모두 다음과 같은 기능을 제공합니다.Data.Bits시프트 및 회전 연산을 포함한 다양한 비트 단위 함수 및 연산자를 포함하는 모듈 및 부울 값을 초과하는 "상자 해제" 배열을 사용하여 비트 배열을 모델링할 수 있지만 이전 모듈에서는 지원되지 않습니다.

Perl에서는 문자열을 확장 가능한 비트 배열로 사용할 수 있습니다.통상의 비트 연산자를 사용해 조작할 수 있습니다(~ & ^vec [5]기능을 사용하여 개별 비트를 테스트하고 설정할 수 있습니다.[4]

Ruby 에서는, 약간의 정수에 액세스 할 수 있습니다(설정할 수 없습니다.Fixnum또는Bignum괄호 연산자( )를 사용합니다.[]비트 배열인 것처럼 표시됩니다.

Apple의 Core Foundation 라이브러리에는 CFBitVectorCFMutableBitVector 구조가 포함되어 있습니다.

PL/I는 임의 길이의 비트 문자열 배열을 지원합니다. 비트 문자열은 고정 길이이거나 가변 길이일 수 있습니다.배열 요소는 정렬할 수 있습니다.각 요소는 바이트 또는 워드 경계에서 시작되거나 정렬되지 않은 요소가 패딩 없이 바로 이어집니다.

PL/pgSQL 및 PostgreSQL의 SQL은 비트 문자열을 네이티브 유형으로 지원합니다.SQL 비트 유형은 두 가지가 있습니다.bit(n)그리고.bit varying(n)여기서 은 양의 [6]정수입니다.

VHDL, VerilogSystemVerilog와 같은 하드웨어 기술 언어는 기본적으로 비트 벡터를 지원합니다. 비트 벡터는 플립 플랍, 하드웨어 버스 및 하드웨어 신호와 같은 스토리지 요소를 모델링하는 데 사용됩니다.OpenVera, eSystemVerilog 등의 하드웨어 검증 언어에서는 비트 벡터는 하드웨어 모델에서 값을 샘플링하고 시뮬레이션 중에 하드웨어로 전송되는 데이터를 나타내기 위해 사용됩니다.

공통 리스프는 1차원의bit-vector빌트인의 특수한 케이스로서의 실장array클래스 및 타입 [7]지정자로서 듀얼 캐퍼시티로 동작합니다.어레이의 파생 모델로서 일반에 의존합니다.make-array구성 요소 유형으로 구성되는 함수bit옵션으로 비트 벡터를 동적으로 크기 조정 가능한 것으로 지정할 수 있습니다.bit-vector그러나 범위가 무한하지는 않습니다.보다 제한적인simple-bit-vectortype이 존재합니다.다이나믹 [8]특성을 명시적으로 제외합니다.비트 벡터는 리더 매크로로 표현되며, 리더 매크로에 의해 보다 간결하게 구성될 수 있습니다. #*bits모든 어레이에 적용되는 일반적인 기능 외에 비트 벡터에 대한 전용 조작이 존재합니다.[9]단일 비트는 다음 명령을 사용하여 액세스 및 수정할 수 있습니다.bit그리고.sbit기능[10] 및 광범위한 논리 연산이 지원됩니다.[11]

「 」를 참조해 주세요.

레퍼런스

  1. ^ "SGI.com Tech Archive Resources now retired". SGI. 2 January 2018.
  2. ^ "dynamic_bitset<Block, Allocator> - 1.66.0". www.boost.org.
  3. ^ ".NET mscorlib source code". github.com/microsoft. 15 October 2021.
  4. ^ "perlop - perldoc.perl.org". perldoc.perl.org.
  5. ^ "vec - perldoc.perl.org". perldoc.perl.org.
  6. ^ "8.10. Bit String Types". 30 September 2021.
  7. ^ "CLHS: System Class BIT-VECTOR". www.lispworks.com.
  8. ^ "CLHS: Type SIMPLE-BIT-VECTOR". www.lispworks.com.
  9. ^ "CLHS: Section 2.4.8.4". www.lispworks.com.
  10. ^ "CLHS: Accessor BIT, SBIT". www.lispworks.com.
  11. ^ "CLHS: Function BIT-AND, BIT-ANDC1, BIT-ANDC2..." www.lispworks.com.

외부 링크