음. 오늘은 갑작스런 회식 예정이 수요일로 잡히면서 교육일정에 치명적인 차질이 생길 수 있다는 이야기를 들었습니다.

 

그러면 우선 2가지에 집중을 해야 하는데, 먼저 출결관리에서 단 1분도 어긋나서는 안되는 것이며 둘째로는 빠지는 강의에 대해서 어떻게 처리를 할 것인가에 대한 해결을 해야합니다.

즐겁고 축하하는 자리인 회식이 뭔....

 

강의에 앞서서 이번에도 사전 Test와 함께 [임베디드 C코드 최적화] 라는 강의 자료화면을 보았습니다.

 

====================================    1    ========================================

(19:03 ~ 19:51 )

강의에 들어가기 앞서서 코드최적화에 대한 이론적인 설명과 필요성에 대해서 이야기를 해 주셨습니다.

게임의 사례를 들면서 최적화의 필요성을 또 이야기 해 주셨습니다. 실수 계산은 CPU에 많은 부담을 주는 연산이라는 것 부터 차근차근 진행을 해 주셨습니다.

CPU가 계산하기 편하도록 부동소수점보다는 고정 소수점을 사용하도록 하고 2의 보수를 사용하기 용이하도록(?) 하는것이 도움이 된다고 하셨습니다.

float 변수에 3.14와 3.25를 넣으면 차이가 남.... 2의 음수승까지 계산을 해보면 됩니다.

우선 최적화를 무조건 할 것이 아니라 어떤 방향으로 최적화를 해야하는지에 대한 지금 개발 환경을 분석하고 결정을 하는 것 또한 중요하다고 하셨습니다.

 

가독성?과 성능은 trade off관계입니다. 최적화를 할 때에는 그래서 어느쪽에 중점을 둘 것인가에 대해 고려를 해야합니다. 현실적으로 모든 조건은 뛰어나게 만드는 것은 쉽지 않기 때문입니다.

 

속도 VS 크기 - H/W단에서는 저장장치의 용량 또한 단가와 상관이 있으며 rom에서 실행하는 것과 RAM에서 실행을 하는 두가지 방법의 차이점도 설명 해 주셨습니다. rom은 속도가 늦지만 code가 RAM에 올라가는 만큼을 절약할 수 있으며, RAM실행을 하면 Memory를 rom code size만큰 memory를 사용하지만 보다 빠른 속도로 동작하는 , 성능이 나은 프로그램을 만들 수 있습니다.

 

====================================    2    ========================================

(20:04 ~ 20:57 )

 

c프로그램에서는 하드웨어에 대한 입출력을 메모리에 입출력하는 것과 같이 처리를 해 줍니다.

두 가지의 방식이 있는데 그중 하나는 Memory Mapped I/O, 나머지 하나는 I/O Mapped I/O입니다. 사용 설명서와 같은 역할을 하는 Data sheet를 확인하여 처리를 할 필요가 있습니다.

Thread??! 가 실타래가 되는...? Android의 Activity는 활동이 되는... 기적을 볼 수 있는 비 전공자의 번역에 대한 농담을 해 주시기도 하셨습니다.

OS는 페이징 기법을 사용하여 메모리에 접근을 하기 때문에 프로그램 상에서 직접 메모리에 접근하는 것을 막습니다. 하지만 OS가 없다면 직접 프로그램 상에서 메모리에 접근을 하여 처리를 할 수도 있습니다.

Valotile Keyword의 의미는 케싱작업을 하지 않는 것이 원 의미이며, 최적화를 하지 않는 것으로도 사용을 할 수도 있습니다.

컴파일러에서 공루프(아무것도 하지 않는 루프), 불려지지 않는 함수등을 제거해버리는 경우도 있습니다.

startup code에 대한 설명과 *.o파일의 구조에 대한 설명을 해 주셨습니다. 지난 주 .bss영역의 초기화가 되지 않은 전역변수가 어떤값을 갖는지에 대한 질문에 대한 저의 오답을 다시한번 생각이 나게 해주셨습니다.

전역변수는 0으로 초기화가 되며 지역변수는 쓰래기값이라고 하는 이상한 값(임의의 값)이 들어가게 됩니다.

H/W가 초기화되려면 부팅에 방해가 되는 요소를 꺼 주어야 합니다. 시스템이 일정 반응이 없으면 재부팅을 해주는 와치독 타이머(watchdog timer)가 동작하지 않도록 해 주어야 합니다. 또한 인터럽트도 의미없는 분기를 막기위해 인터럽트를 꺼두어야 합니다.

그리고 clock를 만들어 주어야 합니다. 그 후 메모리 확인을 해 주고 구성된 H/W중 초기화가 필요한 것들을 초기화 해 줍니다. 그 후 Startup code가 수행됩니다. data와 bss는 RAM으로 이동 후 bss는 0으로 초기화를 해 줍니다.

====================================    B    ========================================

(쉬는시간)

오늘은 첫 시간이라 이론적인 내용으로 수업을 진행한다고 하셨지만 그러면 남은 실습시간은 3일 3시간씩 9시간이고 뭔가 수업이 짧을 것 같다는 느낌이 듭니다.

학부생 시절에 배웠던 임베디디 소프트웨어,하드웨어의 과목 뿐 아니라 전반적인 프로그램의 구조나 리눅스에 대한 내용과 같은 다소 이론적인 내용들이 많이 나왔습니다.

 

====================================    3    ========================================

(21:11 ~ 20:57 )

포인터 난관의 포인터에 대한 설명을 해 주셨습니다. 포인터와 배열은 서로 치환이 되며 서로의 특징을 설명을 해 주셨습니다.

먼저 두개의 포인터를 선언한 후 두 포인터에 대한 사칙연산중 가능 한 것을 고르는 문제가 있었습니다. 과연 어떤 것들이 가능할까요? 먼저 저는 예상을 했을 때 더하기와 빼기가 가능 할 것이라고 생각을 했습니다.

 

하지만 더하기는 불가능 했습니다. 포인터의 연산에서 유일하게 가능 한 것은 빼기연산입니다. 그리고 그 빼기연산의 의미는 두 주소의 차이로 버퍼의 잔량을 구하는 데 사용되기도 합니다. 따라서 그 결과가 음수값이 나오더라도 무방하여 음수값이 나오느냐 양수값이 나오느냐는 위치의 차이일 뿐이라고 설명을 해 주셨습니다.

포인터의 연산에 대해 다시한번 가능 한 것과 불가능 한 것으로 분류하여 설명을 해 주셨습니다.

정수와의 +, -,*, / 단항연산 ++, --, 포인터간의 +, -, *, /, 포인터의 대입연산 (=), 포인터간의 비교연산 (<, >) , 실수와의 +, -, *, / 중에서 어떤것이 가능하고 어떤것이 불가능 할까요?

 

강의 자료로 보면 아하 이렇구나 하고 지나가게 될 것 같아서 한번 직접진행을 해 보는것이 최선일 것 같습니다. 따라서 내일 환경이 구축된 후 이 작업은 꼭 확인을 해 보도록 하겠습니다.

배열과 포인터에서 특히 2차원 배열을 표와같은 형태로 생각을 하는 경우가 있지만 그것은 사람에게 보기 좋게 하기 위한 것일 뿐, 실제로는 메모리에 선형적으로 쓰여있다는 설명을 해 주셨습니다. 또한 배열의 주소연산과 포인터 연산의 관계를 여러가지 예시를 보여주시면서 설명을 해 주셨지만 이해는 반도 못한 것 같습니다.

간단한 퀴즈로 int a[3] = {1,2, 3}일 때

(주소)             (값의 표현)

0x100    a[0]   *a

0x104    a[1]   *a+1

0x108    a[2]   *a+2

일 때 ,

 

1. a, &a의 값은?

2. a+1, &a+1의 값은?

 

위의 문제는 굉장히 간단해 보이면서도 생각을 많이 하게 만들었고 학부생때에도 단 한번도 깊게 포인터를 공부하고 싶지 않게 만든 요인이었습니다. 

내일은 더 이해가 될지도 모르겠지만 오늘은 간단하게 설명을 들은 내용을 정리하는 것으로 마무리를 하겠습니다.

핵심은 *는 선언시에는 주소를 싸는 역할을 하고, 사용시에는 주소를 벗기는 역할을 한다고 합니다.

+ Recent posts