Memory
Β - Last update: 2023-05-14

Memory κ΄€λ ¨ μ—¬λŸ¬κ°€μ§€ 정리. Bit operation으둜 /64 쀄이기 같은 것을 잘 ν•˜λ €λ©΄ μ•Œμ•„μ•Ό ν•˜λŠ” 덕λͺ© 쀑 ν•˜λ‚˜μ΄λ‹€.

μ„œλ‘ 

μš°μ„  이야기λ₯Ό μ‹œμž‘ν•˜κΈ°μ— μ•žμ„œ, μ—¬κΈ°μ„œ μ΄μ•ΌκΈ°ν•˜λŠ” λ©”λͺ¨λ¦¬λŠ” Application κ΄€μ μ—μ„œμ˜ λ©”λͺ¨λ¦¬μ΄λ‹€. 즉, 가상메λͺ¨λ¦¬λ₯Ό λœ»ν•œλ‹€. (물리적인 μ‹€μ œ λ©”λͺ¨λ¦¬λŠ” Appλ‹¨μ—μ„œ 접근도 μ•ˆλœλ‹€) 이 경우, 각 μ‹œμŠ€ν…œμ˜ 아킀텍쳐에 따라 κ°€μš©ν•œ 가상메λͺ¨λ¦¬ 크기가 λ‹¬λΌμ§ˆ 것이닀.

이 κΈ€μ—μ„œλŠ” νŽΈμ˜μƒ 일반적인 32 bit μ‹œμŠ€ν…œκ³Ό 4GB의 λ©”λͺ¨λ¦¬λ₯Ό κ°€μ •ν•΄λ³Έλ‹€. 4GB의 λ©”λͺ¨λ¦¬ μˆ˜μΉ˜λŠ” κ·Έλƒ₯ λ‚˜μ˜¨ 것은 μ•„λ‹ˆκ³ , 32 bit μ‹œμŠ€ν…œμ΄λΌλ©΄ νŽΈν•˜κ²Œ κ°€μ Έκ°ˆ 수 μžˆλŠ” μ£Όμ†Œκ°’ λ˜ν•œ 32 bitκ°€ 되고, 이 μˆ˜κ°€ 0xFFFFFFFFU μ΄λ―€λ‘œ μ‚¬μš©κ°€λŠ₯ν•œ λ©”λͺ¨λ¦¬κ°€ 4GB라고 νŽΈν•˜κ²Œ 이야기 ν•˜λŠ” 것이닀. 단, μ—¬κΈ°μ„œ λ‹¨μœ„λŠ” bit κ°€ μ•„λ‹ˆκ³  byte μž„μ— μœ μ˜ν•˜μž. λ©”λͺ¨λ¦¬ ꡬ쑰상 λΉ„νŠΈλ‹¨μœ„μ˜ 할당은 κ°€λŠ₯ν•˜μ§€λ„ μ•Šκ³  νš¨μœ¨μ μ΄μ§€λ„ μ•Šλ‹€. κ·Έλž˜μ„œ ν•œ μ£Όμ†Œ λ²ˆμ§€μˆ˜ (이λ₯Όν…Œλ©΄ 0x10002411)μ—λŠ” 1 byte = 8 bit의 데이터가 μ €μž₯λ˜μ–΄ μžˆλŠ” 것이닀.

λ©”λͺ¨λ¦¬ ν• λ‹Ή

λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•œλ‹€λŠ” 것은 λ¬΄μ—‡μΌκΉŒ? μ •ν™•νžˆλŠ” 각 ν”„λ‘œμ„ΈμŠ€κ°€ κ°€μ§€κ³  μžˆλŠ” 4GB의 가상메λͺ¨λ¦¬μ— ν• λ‹Ήν•œλ‹€λŠ” 것일 것이닀. ν• λ‹Ήμ΄λž€ λ¬΄μ—‡μΌκΉŒ? λ‚΄κ°€ νŠΉμ • μœ„μΉ˜μ— μžˆλŠ” λ©”λͺ¨λ¦¬ 값을 μ•žμœΌλ‘œ μ‚¬μš©ν•  것이닀 λΌλŠ” 선언이닀. 이 λ©”λͺ¨λ¦¬μƒμ˜ μœ„μΉ˜λŠ” λ‚΄κ°€ λ§ˆμŒλŒ€λ‘œ μ •ν•˜λŠ” 것이 μ•„λ‹ˆλΌ malloc κ³Ό 같은 ν•¨μˆ˜λ₯Ό 톡해 μ–»κ²Œλœλ‹€. 이런 과정이 할당이닀.

할당받은 μ£Όμ†Œκ°’μ€ 32 bit μ‹œμŠ€ν…œμ—μ„œ 32 bitκ°€ λœλ‹€. 이λ₯Όν…Œλ©΄ 0x10002411 μ£Όμ†Œλ₯Ό μ•žμœΌλ‘œ μ“°κ² λ‹€ 라고 ν•œλ‹€λ©΄ μ•žμœΌλ‘œ μ € μ£Όμ†Œμ— μžˆλŠ” 값을 μœ μ˜λ―Έν•˜κ²Œ ν™œμš©ν•˜κ² λ‹€λΌλŠ” 뜻이 λœλ‹€. ν• λ‹Ή μ „μ˜ λ©”λͺ¨λ¦¬ 값은 일반적으둜 보μž₯ν•  수 μ—†λ‹€. λ”°λΌμ„œ ν• λ‹Ήκ³Ό λ™μ‹œμ— λ©”λͺ¨λ¦¬ μ΄ˆκΈ°ν™” μž‘μ—…μ΄ ν•„μš”ν•˜λ‹€.

int* ptr;
malloc(ptr, sizeof(int) * 1000);
memset(ptr, 0, sizeof(int) * 1000);

ν”νžˆ μ„ΈνŠΈλ‘œ μ“°μ΄λŠ” μœ„ C μ½”λ“œκ°€ κ·ΈλŸ¬ν•œ 과정을 κ±°μΉœλ‹€. 총 4 * 1000 byte λ₯Ό ν• λ‹Ήν•˜λ©΄μ„œ 기쑴의 값을 보μž₯ν•  수 μ—†μœΌλ‹ˆ memset을 톡해 μ΄ˆκΈ°ν™”λ₯Ό ν–ˆλ‹€.

그런데, μœ„ 과정은 μ’€ μΆ”μƒμ μœΌλ‘œ λŠκ»΄μ§„λ‹€. μ™œλƒλ©΄, malloc 을 ν†΅ν•΄μ„œ μ£Όμ†Œκ°’μ„ ν• λ‹Ή λ°›λŠ”λ‹€λŠ” 것은 μ•Œκ² λŠ”λ°, μ‹€μ œλ‘œ μ–΄λŠ μ£Όμ†Œκ°’μ„ λ°›λŠ”λ‹€λŠ” 것인지? κ·Έ 해닡이 μ•„λž˜ 그림이닀.

μ‹œμŠ€ν…œμ˜ μ•„ν‚€ν…μ³λŠ” μ΅œλŒ€ν•œ λ‹¨μˆœν•΄μ•Όν•  ν•„μš”κ°€ μžˆλ‹€. 총 4GB 의 λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό ν• λ‹Ήν•  λ•Œ, 쀑간 쀑간 μ£Όμ†Œκ°’μ„ ν• λ‹Ήν•  μˆ˜λ„ μžˆκ² μ§€λ§Œ, 그러면 λ‚­λΉ„κ°€ 생길 κ°€λŠ₯성이 λ†’λ‹€. κ·Έλž˜μ„œ, 크게 μœ„μͺ½λΆ€ν„° (stack), 또 μ•„λž˜μͺ½λΆ€ν„° (heap), λ©”λͺ¨λ¦¬ 곡간을 μ‚¬μš©ν•œλ‹€. μœ„μ—μ„œ μ˜ˆμ‹œλ‘œ λ“€μ—ˆλ˜ malloc 의 경우, heap 곡간을 μ‚¬μš©ν•œλ‹€. heap 은 무더기, 더미와 같은 λœ»μ„ κ°€μ§€λ©° 그림의 μ•„λž˜ 뢀뢄이닀. stack의 경우 μ§€μ—­λ³€μˆ˜λ‚˜ ν•¨μˆ˜ 호좜 μ‹œ μ‚¬μš©λ˜λŠ” 뢀뢄이며 μœ„μͺ½λΆ€ν„° 차게 λœλ‹€. stack 곡간은 일반적으둜 크기가 μ—„μ²­ 크지 μ•Šμ•„ μ œν•œμ΄ μ’€ λΉ‘μ„Ό 편이며, κ·Έλž˜μ„œ μ’…μ’… overflowκ°€ λ°œμƒν•œλ‹€. 이것을 stack overflow 라고 λΆ€λ₯Έλ‹€. (유λͺ…ν•œ μ‚¬μ΄νŠΈλ„ μžˆλ‹€)

stack은 μœ„μ— 짧게 μ–ΈκΈ‰ν•œ κ²ƒμ²˜λŸΌ ν•¨μˆ˜ ν˜ΈμΆœμ‹œμ—λ„ μŒ“μ΄κΈ° λ•Œλ¬Έμ—, μ’…μ’… μž¬κ·€ν•¨μˆ˜λ‚˜ DFSλ₯Ό κ΅¬ν˜„ν•  λ•Œ ν„°μ§€κ²Œ λ˜λŠ” μ›μΈμœΌλ‘œ μž‘μš©ν•˜κΈ°λ„ ν•œλ‹€. 또, μ™œ ν”νžˆλ“€ μ „μ—­λ³€μˆ˜μ—λ‹€κ°€ 배열을 μ„ μ–Έν•˜λŠ”μ§€λ„ μ•Œ 수 μžˆλ‹€. μ΄λŸ¬ν•œ λ©”λͺ¨λ¦¬ ꡬ쑰λ₯Ό μ•Œκ³  λ‚˜λ©΄ ν„°μ§€λŠ” 것을 μ€„μ΄μ§€λŠ” λͺ»ν•˜λ”라도 μ™œ ν„°μ§€λŠ”μ§€λŠ” μ•Œ 수 μžˆλ‹€.

μžλ£Œν˜•κ³Ό λ©”λͺ¨λ¦¬

μœ„μ—μ„œ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°’μ— κ΄€ν•œ 이야기λ₯Ό ν–ˆλ‹€λ©΄ λ‹€μŒμœΌλ‘œλŠ” μžλ£Œν˜•μ— λŒ€ν•œ 이야기가 ν•„μˆ˜μ μ΄λ‹€. μžλ£Œν˜•μ΄ λ©”λͺ¨λ¦¬μ— λ§€ν•‘λ˜λŠ” 방식은 μ•„λž˜μ™€ κ°™λ‹€.

struct mydata
{
int number1;
char string1[15];
int number2;
double floating_point1;
char char1;
float floating_point2;
short short1;
int number3;
double floating_array[3];
} d;
d.number1 = 1234567;
strcpy(d.string1, "Hello world!");
d.number2 = 1;
d.floating_point1 = 2.0;
d.char1 = 1;
d.floating_point2 = 999.999;
d.short1 = 30000;
d.number3 = -1;
d.floating_array[0] = 1.0;
d.floating_array[1] = 2.0;
d.floating_array[2] = 3.0;

μœ„ μ˜ˆμ‹œλŠ” Little Endian을 μ‚¬μš©ν•œ μ˜ˆμ‹œμ΄λ‹€. μ£Όμ˜ν•  점이자 μ•Œλ©΄ 쒋은 점이 두가지가 μžˆλ‹€.

  1. 일반적으둜 int ν˜•μ˜ 경우 4 byteλ₯Ό μ‚¬μš©ν•˜λŠ”λ°, μœ„μ—μ„œ μ–ΈκΈ‰ν•œ κ²ƒμ²˜λŸΌ, λ©”λͺ¨λ¦¬μ˜ κΈ°λ³Έ λ‹¨μœ„λŠ” 1 byte이닀. 즉, 1 byteλ₯Ό μ–΄λ–€ μˆœμ„œλ‘œ 4 byte에 λ°°μ—΄ν•  것인가에 λŒ€ν•œ λ¬Έμ œκ°€ 생긴닀. 이λ₯Ό ν•΄κ²°ν•˜λŠ” 방법이 두가지가 μžˆλŠ”λ°, 보톡 Little Endian, Big Endian 이라고 λΆ€λ₯΄κ³€ ν•œλ‹€. μžμ„Έν•œ λ‚΄μš©μ€ 검색해보도둝 ν•˜μž.
  2. C/C++κ³Ό 같은 μ–Έμ–΄λŠ” ν˜•λ³€ν™˜μ΄ μžμœ λ‘­λ‹€. 이λ₯Όν…Œλ©΄ char ν˜•νƒœμ˜ 배열을 int* p = (int*) charArr;와 같은 μ‹μœΌλ‘œ λ³€ν™˜ν•΄μ„œ μ ‘κ·Όν•  수 μžˆλŠ”λ°, μ΄λ ‡κ²Œ ν•  경우 4byteλ₯Ό ν•œλ²ˆμ— λ‹€λ£° 수 μžˆλ‹€. 이 뢀뢄은 가끔 μ„±λŠ₯을 λ†’μ΄λŠ”λ°μ— 도움이 될 수 μžˆμ–΄μ„œ μ•„λž˜μ™€ 같은 μ˜ˆμ‹œμ½”λ“œλ₯Ό ν•˜λ‚˜ μ²¨λΆ€ν•œλ‹€. λ¬Όλ‘  memset ν•˜λ©΄ λ˜λŠ” 뢀뢄인데 λŒ€μΆ© 이런 λŠλ‚Œμ΄λ‹€ ν•˜κ³  μ΄ν•΄ν•˜κΈ° μ’‹μ•„μ„œ μ²¨λΆ€ν•˜λŠ” 것..
void init(char myArr[1'000'000]) {
unsigned long long *ullp = (unsigned long long*)myArr;
for(int i = 0; i < 125'000; ++i)
ullp[i] = 0;
}

일단 ν”νžˆ μ“°μ΄λŠ” int ν˜•μ— λŒ€ν•΄μ„œ, 숫자 32λ₯Ό λ©”λͺ¨λ¦¬ μ£Όμ†Œ 0xA0000000 에 λ„£κ³  μ‹Άλ‹€κ³  κ°€μ •ν•΄λ³΄μž. μ‹€μ œ λ©”λͺ¨λ¦¬μ— ν•΄λ‹Ή 값이 μ–΄λ–»κ²Œ μ˜¬λΌκ°€ μžˆμ„κΉŒ? (Endian μ‹œμŠ€ν…œμ— 따라 λ‹¬λΌμ§€μ§€λ§Œ.. μš°μ„  Little Endian μ—μ„œμ˜ μ˜ˆμ‹œλ₯Ό μ‚΄νŽ΄λ³Έλ‹€)

0xA00000000xA00000010xA00000020xA0000003
0x200x000x000x00

μ—¬κΈ°μ„œ 32κ°€ μ•„λ‹Œ 0x20이 λ“€μ–΄κ°„ μ΄μœ λŠ” 16진법을 μ‚¬μš©ν•˜κ³  있기 λ•Œλ¬Έμ΄λ‹€. μœ„ ν‘œμ™€ 같이, ν•˜λ‚˜μ˜ μ£Όμ†Œ 곡간에 1 byte κ°€ λ“€μ–΄κ°€κ³ , 총 4 byte 곡간에 κ±Έμ³μ„œ 데이터가 λ“€μ–΄κ°”λ‹€.

μ˜ˆμ‹œλ₯Ό ν•˜λ‚˜λ§Œ 더 보자. μ΄λ²ˆμ—” λ¬Έμžμ—΄ "Hello" κ°€ 같은 곡간에 μ €μž₯될 κ²½μš°μ— μ–΄λ–»κ²Œ 될지 λ³Έλ‹€.

0xA00000000xA00000010xA00000020xA00000030xA00000040xA0000005
0x480x650x6C0x6C0x6F0x00

이제 감이 거의 λ‹€ 왔을 것이닀. 각 μˆ«μžλ“€μ€ ASCII ν˜•μ‹μœΌλ‘œ 인코딩 된 것이며(μžμ„Ένžˆ λ“€μ–΄κ°€λ©΄ λ‹€λ₯Έ 인코딩 ν˜•νƒœλ₯Ό μ“΄λ‹€λ©΄ 1 byteλ‘œλŠ” λΆ€μ‘±ν•œ κ²½μš°λ„ μžˆλ‹€), 맨 끝 μ£Όμ†Œμ— μžˆλŠ” 값에 0x00이 μžˆλŠ” 것을 λ³Ό 수 μžˆλŠ”λ° 이것은 ν”νžˆ μ΄μ•ΌκΈ°ν•˜λŠ” NULL λ¬Έμžμ—΄μ„ μ˜λ―Έν•œλ‹€. 이게 μ—†λ‹€λ©΄ μ–΄λ””κΉŒμ§€κ°€ λ¬Έμžμ—΄μ˜ 끝인지 μ•ŒκΈ°κ°€ μ–΄λ €μšΈ 것이닀.

char[] ν˜•νƒœκ°€ 쑰금 νŠΉλ³„ν•˜κ³ , short, int, long long의 경우 길이의 차이만 μžˆλ‹€. 그리고 λ¬Όλ‘  float, double도 μžˆλŠ”λ° 이것은 IEEEμ—μ„œ μ •ν•œ νŠΉλ³„ν•œ μ§€μˆ˜, κ°€μˆ˜λ₯Ό λ‚˜λˆ  ν‘œκΈ°ν•˜λŠ” 방법이 μžˆμœΌλ‹ˆ κ΄€μ‹¬μžˆμœΌλ©΄ μΆ”κ°€λ‘œ 찾아보도둝 ν•˜μž. μ–΄μ°Œλλ“  이듀 λͺ¨λ‘λŠ” 맨 μ•ž λΉ„νŠΈ(MSB)λ₯Ό 톡해 λΆ€ν˜Έλ₯Ό νŒμ •ν•  수 μžˆλŠ” 것은 곡톡적이닀.

bool isNegative(int v) {
const unsigned int mask = 0x80000000U;
return ((unsigned int) v & mask);
}

각쒅 ν™œμš©

μœ„ λ‚΄μš©μ€ ν”νžˆλ“€ λ‹€λ“€ μ•ˆλ‹€κ³  μƒκ°ν•˜λŠ” λ‚΄μš©μ΄λ‹€. ν•˜μ§€λ§Œ μ΄λŸ¬ν•œ μ„±μ§ˆλ“€μ„ ν™œμš©ν•˜λŠ” 것은 λ˜λ‹€λ₯Έ λ¬Έμ œμ΄λ‹€. μš°μ„ , 이런 ꢁ금증이 μžˆμ„ 수 μžˆλ‹€. νŠΉμ • λ©”λͺ¨λ¦¬ 곡간은 1 byte λ‹¨μœ„λ‘œ 밖에 μ‚¬μš©ν•  수 μ—†λŠ”κ°€? 예λ₯Όλ“€λ©΄, κ²½μš°μ— 따라 ASCIIλ₯Ό μ“°λŠ” 1 byte 쑰차도 μ•„κΉŒμš΄ κ²½μš°κ°€ μžˆμ„ 수 μžˆλ‹€. 5λΉ„νŠΈλ‘œ ν‘œν˜„μ΄ κ°€λŠ₯ν•œ λ¬Έμ œμ—΄λ§Œ μ˜¨λ‹€κ³  헀을 λ•ŒλŠ” 5λΉ„νŠΈλ§Œ μ‚¬μš©ν•΄μ„œ 문자λ₯Ό λ‚˜νƒ€λ‚΄λŠ”κ²Œ μ΅œμ μΌν…λ°, 그러면 μ΄λŸ¬ν•œ λΉ„νŠΈλ‹¨μœ„ μ‘°μž‘μ΄ ν•„μš”ν•œ κ²½μš°λŠ” μ–΄λ–»κ²Œ ν•΄κ²°ν•  수 μžˆμ„κΉŒ?

λΉ„νŠΈλ‹¨μœ„ λ™μž‘μ€ κ΅¬ν˜„ν•˜κΈ°μ— 따라 μ—„μ²­λ‚˜κ²Œ λΉ λ₯Ό μˆ˜λ„ 있고 느릴 μˆ˜λ„ μžˆλ‹€. 일단은 느린 λ°©λ²•μœΌλ‘œ λ¨Όμ € μ—°μŠ΅ν•΄λ³΄κ³ , 각쒅 λ‘œμ§λ“€μ„ 빨라지도둝 μˆ˜μ •ν•΄λ³΄μž. μš°μ„ , λ©”λͺ¨λ¦¬ 곡간은 char[]에 λŒ€μ‘λœλ‹€. μ‹€μ œ μ£Όμ†Œμ˜ μ΅œμ†Œ λ‹¨μœ„κ°€ 1 byte λ‹¨μœ„μ΄κ³ , char의 크기도 1 byteμ΄λ‹ˆ μ²œμƒμ—°λΆ„μ΄λ‹€. 이 λ°°μ—΄μ˜ 초기 μ‹œμž‘ μ£Όμ†Œλ₯Ό μ‚¬μš©ν•˜κ³ μž ν•˜λŠ” λ©”λͺ¨λ¦¬μ˜ μ‹œμž‘ μ£Όμ†ŒλΌκ³  ν•˜μž. 그러면 n λΉ„νŠΈ λ’€μ˜ 곡간(n λ°”μ΄νŠΈκ°€ μ•„λ‹˜μ— 유의)은 μ–΄λ–»κ²Œ μ ‘κ·Όν•  것인가? μ•„λž˜μ²˜λŸΌ ν•  수 μžˆλ‹€.

bool getBit(char arr[], int bitpos) {
return (arr[bitpos >> 3] & (bitpos & 0x7)) != 0;
}

>> 3은 / 8κ³Ό λ™μΌν•œ 효과이며, 0x7은 % 8κ³Ό λ™μΌν•œ νš¨κ³Όμ΄λ‹€. μœ„ λ‘œμ§μ€ μ•„μ£Ό μ•„λ¦„λ‹΅κ²Œ λ™μž‘ν•œλ‹€. setBit도 μœ μ‚¬ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

bool setBit(char arr[], int bitpos) {
return arr[bitpos >> 3] |= 1 << (bitpos & 0x7);
}

O(N/64)의 맀직

그런데, μ–΄λŠμ„Έμ›”μ— λΉ„νŠΈλ₯Ό ν•˜λ‚˜μ”© 켜고 μžˆκ² λŠ”κ°€? νŠΉνžˆλ‚˜ μš°λ¦¬λŠ” μ„±λŠ₯ μ΅œμ ν™”λ₯Ό ν•˜λ €κ³  이런 Low Level을 배우고 μžˆλŠ” 것이지 λΉ„νŠΈλ₯Ό ν•˜λ‚˜μ”© 켜고 끄렀고 배우고 μžˆλŠ” 것이 μ•„λ‹ˆλ‹€. μ–΄λ–€ λ©”λͺ¨λ¦¬μƒμ˜ 값을 ν•œλ²ˆμ— λ°”κΏ€ λ•ŒλŠ” κ°€λŠ₯ν•˜λ©΄ κ°€μž₯ 큰 λ‹¨μœ„ 둜 ν•˜λŠ” 것이 μ’‹λ‹€. λ§Œμ•½μ— λ©”λͺ¨λ¦¬μƒμ˜ λΉ„νŠΈλ₯Ό 01010101...와 같은 μ‹μœΌλ‘œ μ„ΈνŒ…ν•˜κ³  μ‹ΆμœΌλ©΄ μ–΄λ–€κ°€? μ•„λž˜μ²˜λŸΌ ν•˜λ©΄ λ‚­λΉ„λ‹€.

for (int i = 0; i < MAX_POS; ++i) {
if (i & 1) setBit(arr, i);
}

μœ„ μ½”λ“œλŠ” μ˜λ„ν•œλŒ€λ‘œ 틀림없이 λ™μž‘ν•  κ²ƒμ΄μ§€λ§Œ, unsigned long long μ΄λΌλŠ” 64 bit μžλ£Œν˜•μœΌλ‘œ 64λ°° λΉ λ₯΄κ²Œ λ§Œλ“€ 수 μžˆλ‹€. (μ—„λ°€ν•˜κ²ŒλŠ” λ°°μ—΄ 크기가 컀짐에 따라 L1 / L2 μΊμ‹œ 등을 μƒκ°ν•˜λ©΄ 64λ°°κΉŒμ§€λŠ” 아닐 수 μžˆκ² μ§€λ§Œ μ•„λ¬΄νŠΌ 빨라진닀)

unsigned long long mask = 0x5555555555555555ULL;
unsigned long long *ullp = (unsigned long long*) arr;
for(int i = 0; i < MAX_POS / 64; ++i) {
ullp[i] = mask;
}

0x5555...λŠ” 0101... 이 μ—°μ†μ μœΌλ‘œ μžˆλŠ” κ²ƒμ˜ 16μ§„μˆ˜ ν‘œν˜„μ΄λ‹€.

μž„μ˜ bit 수의 데이터 연속 μ“°κΈ°

λ§Œμ•½, μ•„λž˜μ™€ 같은 μ„Έ μ’…λ₯˜μ˜ λΉ„νŠΈ μ„ΈνŠΈλ₯Ό κ³„μ†ν•΄μ„œ write ν•΄μ•Όν•˜λŠ” 경우λ₯Ό μƒκ°ν•΄λ³΄μž. Huffman μ½”λ”©κ³Ό 같은 κ³³μ—μ„œ μ‚¬μš©λ˜λŠ” case일 수 μžˆκ² λ‹€.

  1. 0
  2. 10
  3. 11

μ“°κ³ μž ν•˜λŠ” λ°μ΄ν„°λŠ” 01011100001011κ³Ό 같이 될 것이닀. 원본 λ°μ΄ν„°λŠ” int oData[]에 μ €μž₯λ˜μ–΄ μžˆλ‹€κ³  ν•˜μž. Naiveν•˜κ²ŒλŠ” μ•„λž˜μ²˜λŸΌ κ΅¬ν˜„λœλ‹€.

int bitpos = 0;
for (int i = 0; i < DATA_SIZE; ++i) {
switch (oData[i]) {
case 1:
++bitPos;
break;
case 2:
++bitPos;
setBit(arr, bitPos++);
break;
case 3:
setBit(arr, bitPos++);
setBit(arr, bitPos++);
break;
}
}

그런데, 이것을 LUTλ₯Ό ν™œμš©ν•΄μ„œ 뢄기없이 μ²˜λ¦¬ν•  수 μžˆλ‹€.

char* p = arr;
int offset = 0;
for (int i = 0; i < DATA_SIZE; ++i) {
p |= LUT[offset][oData[i]];
p += LUT_NEXT[offset][oData[i]];
offset += LUT_SIZE[oData[i]];
offset &= 0x7;
}

μ—¬κΈ°μ„œ 쓰일 수 μžˆλŠ” LUT κ΅¬ν˜„μ€ 직접 ν•΄λ³΄μž.

참고자료

🏷️ 주제 λͺ©λ‘: