본문 바로가기

programmer/Embedded

Union 사용 이유

 

기본 설명

Union 은 한국말로 공용체라고 한다. 뭔가를 공용으로 사용하는 놈이라고 생각되는데 왜 Union을 사용해야 하고 어디에 쓰이는지 예시를 통해 설명하도록 하겠다.

설명은 하기 목차대로 진행한다.

1. 왜 필요한가.

2. 프로그래밍 예시

 

1. 왜 필요한가.

TV 셋탑 박스를 개발해야 하는 2명의 개발자가 있다. A라는 개발자는 프로그램을 64G 이하로 개발하였고 B라는 개발자는 프로그램을 100G 이상으로 개발하였다. 1000대 이상의 셋탑 박스를 생산해야 하는 회사의 입장에서는 생산단가 절약으로 인한 매출과 경쟁력을 갖추기 위해 A 개발자를 선택 할 것이다. (아는게 돈이고 경쟁력이다.)

하기의 이미지는 메모리 가격을 확인하기 위해 Mouser에서 검색해본 결과이다. 메모리 크기에 따라 단가는 2배 이상 차이가 난다. 결코 저렴하지 않다. 임베디드 개발자라면 자신이 개발한 프로그램의 메모리 사용량을 최소화 및 최적화할 필요가 있다.

20.03.18 기준 INAND 메모리 가격

실 예시 2) 삼성 PCB 회로

실 예로 S 전자에 다니던 한 연구원은 입사 후 기존의 PCB 회로의 아주 극소 부분을 더 최적화한 방안으로, 회로만 다른 쪽으로 터주는 방식을 제안했다. 의견이 받아들여져 모바일 대당 몇 십 원단위의 예산이 감산되었고(이말을 들은지 오래되서 정확히 기억은 안나지만 몇 억 단위라고 했다.) 이후 이 연구원은 고속 승진을 하게 된다.

우리는 PCB 까지는 둘다 알면 좋겠지만, union을 사용하면 메모리는 확실하게 줄일 수는 있다. 이 부분에 대해서 좀 더 알아보자.

 

2. 프로그래밍 예시

C 언어 자료형 크기

 

프로그래밍 예시를 들기 전에 상기 이미지와 같이 우리가 흔히 사용하는 C 언어 변수들의 크기를 정확히 알아야 한다. 전쟁 나가기 전 내가 든 소총이 몇 mm 탄을 쓰는지, 연사가 되는지, 사거리는 얼마인지 알아야 하는 것과 같다.

프로그래밍 조건 1: TV 셋탑 박스 사용자 등록 프로그램을 개발한다. 이 셋탑박스는 5천만의 사랑을 받고 있지만, 메모리는 턱없이 부족해서 사용자 1명당 저장할 수 있는 메모리의 크기는 20byte 한정되어 있다. 사용자 등록은 주민 번호로 구분한다.

A라는 개발자는 Struct로 사용자 정보를 저장한다.

struct
{
    unsigned char resident_registration_number[13]; //13byte
}Man_id_s


void main()
{

	Man_id_s suho;
	suho.resident_registration_number = 1111112222222;

	return;
}

B라는 개발자는 Union으로 사용자 정보를 저장한다.

union
{
    unsigned char resident_registration_number[13]; //13 byte
}Man_id_s


void main()
{

	Man_id_s suho;
	suho.resident_registration_number = 1111112222222;

	return;
}

 

A, B 개발자 모두 잘 개발하였다. 메모리 크기 20byte 안에 한 명의 정보를 저장했다.

모두 다 행복하다. 하지만 사회가 그것을 용납하지 않는다.

 

대한 민국 주민번호 수집 법정주의

 

2017년도부터 주민 번호를 사용자 인식 수단으로 사용하지 말라는 법령이 공포된다. 그래서 이 회사는 전화번호를 사용해 ID를 잡으려 한다. 하지만 이미 팔린 주민번호를 사용하는 셋탑 박스가 있으므로, 기존 셋탑 박스를 동일하게 사용하면서 전화번호 등록도 가능한 셋탑 박스를 개발 하도록 요청한다. 메모리는 기존과 동일하게 20byte 제한이다.

프로그래밍 조건 추가: 기존 주민번호도 사용하면서 새로운 등록자에겐 전화번호를 등록하도록 한다. (하드웨어는 동일하고 펌웨어만 업그레이드 하자.)

A라는 개발자는 기존에 사용했던 Struct로 사용자 정보를 추가한다.

struct 
{ 
    unsigned char resident_registration_number[13]; //13byte 
    unsigned char phone_number[11]; //11byte
}Man_id_s 


void main() 
{ 

Man_id_s suho; //13 + 11 byte = 23 byte (메모리 오버)
suho.phone_number = 01011112222; 

return; 
}

하지만 기존 방식을 그대로 사용한다면 struct의 총 메모리는 23 byte이다.

B라는 개발자는 Union으로 사용자 정보를 저장한다.

union 
{ 
    unsigned char resident_registration_number[13]; //13byte 
    unsigned char phone_number[11]; //11byte
}Man_id_s 


void main() 
{ 

Man_id_s suho; //13 | 11 byte = 13 byte (메모리 커버)
suho.phone_number = 01011112222; 

return; 
}

 

B라는 개발자는 기존의 주민번호도 사용하게 가능하고 새로 팔리는 셋탑박스에 휴대폰 정보로 사용자 등록을 완료한다.

이 회사는 다행히 B의 개발자의 도움으로 해당 법률을 만족시킨다.

 

여기서 struct 와 union의 메모리 할당 방식에 대해 알아보도록 한다.

(단순 설명을 위한 자료로 벤더 사 별 메모리 저장 방식(Endian)을 고려하지 않는다.)

Struct의 메모리 할당 구조

Struct 메모리 구조

Union의 메모리 할당 구조

Union 메모리 구조 이해를 위한 이미지 (1/3) -꼬부기
Union 메모리 구조 이해를 위한 이미지 (2/3)-어니부기
Union 메모리 구조 이해를 위한 이미지 (3/3)-거북왕?

Union은 상기 이미지 마지막의 'Union 메모리 구조 이해를 위한 이미지 (3/3)' 와 같은 메모리 구조를 갖는다. 위의 자료형 별 표에서 char, int, long 등의 자료형과 마찬가지로 C 문법은 위와 같은 자료형 구조체를 제공한다. 이러한 메모리적 특성 때문에 기존 주민번호를 사용할 때는 13byte를 사용하고 전화번호를 사용할 때는 11byte만 사용 가능하게 되는 것이다.(배열은 0부터 시작)

따라서 B 개발자는 Union의 자료형 특징을 사용해 2가지 ID 를 구분하면서 메모리를 절약하게 되는 것이다.

 

총 정리

모든 프로그램은 하드웨어 위에 돌아간다. 따라서 우리가 개발하는 모든 프로그램은 하드웨어의 제약을 고려해야 한다. 그것은 개발자가 설계한 효율적인 메모리 사용일 수도 있고 최적화 로직(알고리즘) 등이 될 수 있다. 앞서 설명한 B의 개발자와 같이 경쟁력있는 프로그래머가 되기 위해서 union과 같이 사소한 것이라도 놓치지 않도록 하자.

반응형
사업자 정보 표시
라울앤알바 | 장수호 | 서울특별시 관악구 봉천로 13나길 58-10, 404호(봉천동) | 사업자 등록번호 : 363-72-00290 | TEL : 010-5790-0933 | Mail : shjang@raulnalba.com | 통신판매신고번호 : 2020-서울관악-0892호 | 사이버몰의 이용약관 바로가기