멀티태스킹 운영체제에는 한 주소 공간에 여러 프로그램들이 동시에 실행될 수 있다. 그렇기 때문에 그런 환경에서 동작하는 프로그램이라면 자기가 메모리의 어느 위치에 적재되는지를 신경써야 하며, 임의의 위치에 올라가더라도 잘 실행될 준비가 되어 있어야 한다.

과거 도스 시절에는 EXE말고 COM이라는 실행 파일이 있었는데, 이것은 최소한의 헤더 같은 것도 없고 코드와 데이터가 다 16비트 공간 안에 막혀 있으며(과거 메모리 모델로 치면 제일 작은 tiny와 동일), 메모리 주소도 고정 붙박이식이어서 오늘날의 컴퓨터 환경과는 도저히 어울릴 수 없는 과거 유물이 되어 있다.

윈도우 운영체제의 실행 파일이 사용하는 PE 포맷은 position dependent code 방식이다. 즉, preferred base라는 개념이 존재하여 자기는 32비트 주소 공간에서 어디에 적재되는 게 이상적인 경우라고 이미 가정하고 만들어져 있다는 뜻이다. 어떤 EXE나 DLL이 거기에 바로 적재가 가능하다면 가장 빠르고 좋지만, 만약 이 선호하는 주소에다 적재가 못 된다면 별도의 재배치 작업이 필요하다. 즉, 마치 퀵 정렬처럼 잘 될 때와 못 될 때의 성능 편차가 크며 일종의 모험이 동반된다는 뜻이다.

이는 유닉스의 shared library와는 다른 디자인이다. 그쪽은 이렇다할 preferred base 주소가 없으며, 코드 자체가 어느 메모리 주소에 적재되든 동일한 성능으로.. 하지만 딱히 최적의 성능을 발휘하지는 않는 구도로 동작한다. 일종의 힙 정렬이나 병합 정렬처럼 동작한다는 뜻.

윈도우 PE 포맷에는 실제로 실행되는 기계어 코드인 code 섹션도 있고 data라든가 리소스(rsrc)와 더불어 재배치 정보를 나타내는 섹션(reloc)도 있다. preferred base에서 동작하지 못할 때, 코드의 어느 부분을 쫙 수정해 주면 preferred base가 아닌 다른 지점을 기준으로 이 프로그램이 잘 돌아갈 수 있는지를 따로 기록해 놓은 것이다. 사실 이런 개념의 재배치 정보는 도스 EXE나 16비트 윈도우 EXE에도 있긴 했다.

그런데 32비트 윈도우 EXE만은(물론 64비트도 포함) 원칙상 이런 재배치 정보가 필요하지 않게 됐다. 32비트 환경부터는 모든 EXE들이 나만의 독립된 주소 공간을 가지기 때문에, preferred base가 무엇이든지에 무관하게 EXE는 무조건 내가 원하는 위치에 가장 먼저 적재되는 게 보장되기 때문이다.
그래서 통상 EXE들은 재배치 정보를 넣지 않는다. 필요가 없기 때문에, 넣지 않는 게 파일 크기를 줄이는 데도 도움이 되기 때문이다.

그럼에도 불구하고 재배치 정보가 필요한 경우는 다음과 같다.

1. EXE가 아닌 DLL은 반드시 필요하다. DLL은 다른 EXE의 밑에 붙어서 동작한다는 특성상 자신만의 주소 공간을 갖고 있지 않다. 나의 preferred base에 EXE라든가 다른 DLL이 이미 선점되어 있다면 응당 재배치가 필요하다. DLL은 그런 상황을 언제든지 대비해야 한다.

2. Win32s에서 돌아가는 32비트 프로그램이라면 EXE라도 재배치 정보가 반드시 있어야 한다. Win32s는 과거 윈도우 3.1에서 일부 32비트 프로그램을 구동하기 위해 제공되었던 일종의 운영체제 익스텐더로, 32비트 프로그램을 실행만 해 줄 뿐, 16비트 윈도우 3.1이 지니고 있던 시스템적인 한계는 그대로 답습하고 있다.
멀티스레딩을 지원하지 않으며 32비트까지 포함해 모든 EXE가 독립이 아니라 단일 주소 공간을 공유한다!
프로그램을 실행할 때마다 EXE의 핸들이 제각각인 값이 들어오며, 로딩도 preferred base에 정확하게 절대로 되지 않는다. 여기에 대해서는 추후 실험해 볼 예정.
실제로 테스트를 해 보면 핸들이 0x1xxx 이렇게 아주 작은 값으로 들어온다는 게 매우 흥미롭다. 윈도우 NT에서는 그렇게 낮은 주소는 아예 무조건 에러로 간주하는 반면, Win32s에는 그게 여전히 쓰인다는 소리이다. 포인터가 아니라 진짜로 다른 번호에 가깝다.

3. 비주얼 C++ 2008에서 추가된 '시작 주소 랜덤화' 기능을 사용하려면 재배치 정보가 필요하다.
보안을 위해 성능을 희생하듯, 윈도우 비스타부터는 PE 실행 파일도 일종의 position independent (과거의 dependent가 아닌) code처럼 써먹으려는 것 같다.
이 방식으로 빌드된 EXE는 운영체제가 일부러 EXE의 preferred base와는 다른 임의의 위치에다가 로딩을 해 준다. 즉, 이 EXE의 특정 지점의 코드나 데이터를 딱 맞춰 수정하는 프로그램이 제대로 동작하지 않게 위해서이다. (스타크로 치면 맵핵 같은 프로그램)

Posted by 사무엘

2010/05/04 08:36 2010/05/04 08:36
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/258

금 이야기

금과 은, 특히 금은 동서고금을 막론하고 인류에게 값비싼 귀금속의 제왕으로 각인되어 왔으며 성경적인 의미도 풍부하다. 하나님은 이 세상의 물질도 귀한 것과 흔해빠진 것을 구분해 놓으신 것이다.
사람이라면 본능적으로 누구라도 번쩍이는 누런 금을 보면 아름다움을 느끼고, 탐내고 갖고 싶어할 것이다. 금은 어디서나 보편적인 ‘경제적 값어치’를 지니고 있다. 그래서 현찰만큼이나 검은 거래에서 쓰이는 매개체가 되기도 쉽다. 흔한 물질로부터 금을 만들려고 애썼던 연금술, 그리고 미국 서부 개척 시대의 골드러시를 우리는 역사를 통해 기억한다.

잘 알다시피 올림픽에서는 상위 입상자에게 금· 은· 동메달이 수여된다. 그런데 1차 세계 대전의 직전에 개최된 1912년 제 6회 대회까지는 메달을 단순 도금이 아닌 진짜 순금· 순은으로 만들어서 줬다는 것도 흥미로운 사실이다. 흠좀무... 그렇게 해서는 올림픽 위원회의 재정이 남아나질 못했을 것이다.

금은 잘 알다시피 일단 외형이 정말 탐스럽다. 그런데 희귀하다.
그리고 매우 안정적이다. 공기 중에서 녹이 전혀 슬지 않으며, 수중이나 고온에서도 산화하지 않고 어지간한 화학 물질에도 반응하지 않는다. (뭐, 왕수 같은 일부 물질에는 녹지만) 제아무리 금이 보기에 아름다워도 공기 중에 조금만 놔 두자 쇠처럼 녹이 슨다면, 이 정도로 비싼 귀금속의 지위를 차지할 수 없을 것이다. 이렇듯 불변성 역시 금의 매우 중요한 특징이다.

금은 액세서리를 만들 때뿐만이 아니라 그 안정성과 불변성 덕분에 치과 의료용으로도 쓰이고, 전기적 특성 덕분에 손전화 같은 전자 기기에도 소량 들어간다. 오죽했으면 그런 반도체 기판을 만드는 회사에서 수거되는 금을 몰래 빼돌린 직원이 경찰에 잡히기도 했을 정도이다.

태양계 바깥으로 떠난 우주 탐사선 파이어니어 10호와 11호에는 혹시 외계인이 발견하면 보라는 의도로 지구의 위치와 인간의 모습 등이 새겨진 일명 ‘파이어니어 금속판(Pioneer plaque)’이 장착되었는데 이 금속판의 재질은 알루미늄에다 금 도금이다. 11호에는 아예 금으로 만들어진 LP 음반까지 들어있다(지구의 소리 수록). 그야말로 지금까지의 인류 역사보다 더 긴 시간 동안 여행할지도 모르는데 변질되지 말라고 비싸고 무거운 금을 쓴 게 틀림없다.

또 금은과 비슷하게 안정적인 금속으로 백금이 있다. 백금은 촉매로도 실용성이 매우 뛰어난 금속이며, 백금과 이리듐(Ir)이라는 희소 금속과의 합금은 전자 장비의 접촉 부품, 만년필 펜촉 등으로도 쓰이고 측정 기기의 재질로 활용된다. 특히 과거에 킬로그램 원기, 미터 원기 같은 물건도 안정성 덕분에 이 합금으로 만들었을 정도이니 말 다 했다. 손전화 같은 정밀 전자 기기를 만들 때 쓰이는 이런 희소 금속들을 확보해 놓으려는 경쟁도 국가간에 치열하다고 소식을 전에 들은 것 같다.

은만 있는 게 아니라 수은도 있고, 금만 있는 게 아니라 백금도 있다는 게 흥미롭다. 백금과 은의 차이는 마치 여성 친구(female friend; 그냥 우정)와 여자 친구(girl friend; 애인-_-)의 차이인 것 같다. ^^;;

성경에는 예수님이 태어났을 때 동방 박사들이 그분께 바친 선물 세 종류 중에도 금이 있었다(마 2:11).
뭐니 뭐니 해도 황금 잔치가 벌어졌던 때는 솔로몬 왕 시절인데, 궁내 경비병들에게 지급된 방패의 재질이 금이었고 왕좌도 금이었으며, 왕이 사용하는 식기조차 다 금이었다! (왕상 10:14-22, 27)

은은 길거리에 굴러다니는 돌멩이마냥 흔해 빠졌고 아예  하찮은 것으로 여겨졌다니 믿어지는가? (왕상 10:27) 그때는 사실상 전세계의 모든 금이 예루살렘으로 몰렸다는 소리이다. 조금 상식이 있다면 불신자라도 666이라는 숫자가 아주 나쁜 의미로 성경에 나온다는 걸 알 텐데, 계시록에만 666이 있는 게 아니다. 1년 동안 솔로몬의 왕국으로 반입된 금의 무게가 666달란트(약 20~25톤)였다고 한다. 성경에서 666이 딱 두 번 이렇게 나온다는 게 아주 흥미로운 사실이다.

뭐 그래 봤자 금으로 도배를 해 놨던 성전과 각종 집기들은 이스라엘 민족이 망할 때 다 외적들에게 뺏겼다. 예수님은 헤롯 시절에 지어진 성전이 “돌 위에 돌 하나 안 남기고 다 무너질 것”이라고 예고하신 적이 있는데(마 24:2), 이것은 유대인들의 민족 자존심을 건드리는 발언이요, 마치 “제아무리 불침선 타이타닉이라고 해도 처녀 항해 때 싹 침몰해 버릴 것이다” 같은 메가톤급 예언이었다.
하지만 예언은 그대로 적중. 왜 성전이 돌 위에 돌 하나 안 넘기고 무너졌는가 하면, 탐욕스러운 적군들이 금을 추출하려고 돌을 하나하나 다 뒤지고 녹였기 때문이었다고 한다. 정말 ‘지못미 성전’이다.

그래도 안타까워하지 말자. 예수님께서 그 황금 잔치를 벌였던 솔로몬의 영광도 보잘것없다고 말씀하시며(마 6:29), 자신이 솔로몬보다도 더 큰 이(마 12:42)라고 소개하시기 때문이다. 그리고 구원 받은 크리스천이 하늘나라에서 살게 될 곳은 도시 전체가 맑은 유리 같은 순금일 테니 말이다(계 21:18).

이상, 4월의 마지막 블로그 포스트였다. ^^

Posted by 사무엘

2010/04/30 21:35 2010/04/30 21:35
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/256

※ 스크린도어

지금까지 전문 지하철 회사들에 비해 스크린도어 설치에 인색한 편이던 코레일도,
올해부터 전철 승강장 -- 그것도 분당선이나 과천선 같은 곳이 아닌 지상 승강장에 스크린도어를 설치하려는 움직임을 보이고 있다.
용산과 가산디지털단지 역에 설치 중인 걸 확인했고, 경인선은 역시 이용객이 많아서인지 송내 등 상당수의 역이 이미 공사가 시작되어 있다.

앞으로 이런 지상 국철 구간 승강장에서 일반열차가 주행하는 걸 촬영하기도 더욱 힘들어질 것 같다.
지하 구간인 분당선· 과천선· 일산선엔 저런 거 언제 들어오려나?

일본은 전동차 운전실 모습까지 유리창으로 보여준다. 대부분의 역에 스크린도어 같은 건 없다. 누가 승강장 투신 자살이라도 하면, 사회에 민폐 끼친 책임을 지라고 유족에게 되려 벌금을 매긴다. 이런 일본과 한국은 철도 인프라도 다르지만 그 문화 내지 정서도 상당히 다르다. ^^;; (일본이 운임도 더 비싸고 승객을 더 자비심 없이 대하고 더 짐짝 취급한다. 단지 철도로 갈 수 있는 곳이 더 많고 정시성이 더 뛰어난 정도?)

스크린도어 관련 추가 잡설:
- 가까운 미래에 개통을 앞두고 있는 용인 경전철은 이례적으로 스크린도어가 설치되지 않는다. 어차피 차량이 레일 위를 달리는 1량짜리 버스 수준에 불과한지라 선로 추락 사고가 나도 차를 급정거로 세우기 쉬운 편이며, 그런 사고라도 나면 무인 통제실에서 신속하게 대처가 되기 때문이라 한다.

- 아무리 그래도 차량 기지 임시역에까지 값비싼 스크린도어를 설치해 주지는 않는다. (7호선 장암, 9호선 개화) 그런데 광주 지하철 1호선의 녹동 역은 현재 국내에서 유일한 로프 셔터(?)가 설치되어 있다. 평소에는 이게 마치 상가의 셔터처럼 내려와서 승객과 선로 사이를 차단하고 있다가 열차 문이 열리면 그게 스르륵 위로 올라간다. 그러므로 선로와 승강장 사이에 공기는 통하기 때문에 열차풍 차단 효과는 없지만, 어쨌든 선로 투신은 확실하게 방지 가능하며, 로프 사이에다 카메라를 집어넣어서 선로를 촬영하는 것도 가능하다. 꽤 저렴하고 실속 있는 선택이라는 생각이 든다.

※ 중국· 일본어 안내방송

최소한 2009년쯤부터 SMRT 도철 5~8호선의 안내 방송에 묘한 변화가 생겼다.
잘 알다시피 환승역이나 비환승이더라도 이용객이 많은 주요역에는 중국· 일본어 방송이 추가됐다.
그리고 시종착역 뿐만 아니라 환승역 방송 후에도 일부 노선은 '5678 서울 도시철도' CM송이 끝에 추가됐다. 이 사실 자체에 대해서는 본인이 예전에도 비슷한 글을 블로그에 남긴 적이 있다.
그런데 재미있는 건 모든 노선에서 그러고 있지는 않다는 것.

(거의) 모든 환승역에서 중국어와 일본어 안내방송을 덩달아 하는 곳: 6, 7호선
5호선도 종로3가, 공덕, 광화문 등 주요역에서는 중국어와 일본어 방송을 하지만 왕십리 이후의 동쪽이나 여의도 이후의 서쪽에서는 하지 않는다. 하다못해 동대문역사문화공원 역에도 안 하며, 8호선에은 유일하게 그런 방송이 전혀 없다.

환승역 방송 후 "5678 서울 도시철도" 로고송이 나오는 곳: 7, 8호선
거 참 신기하지 않은지? 오로지 저 두 노선에서만 하고 있다.

따라서 이 두 방송을 모두 적극 실시하는 7호선이 안내방송 러닝 타임이 제일 길어져 있다.
본인은 시도 때도 없이 서는 지하철에서 일일이 4개 국어 방송이 다 나가는 거 별로 찬성은 안 한다. 역 안내 방송은 언어가 중요한 게 아니라 역명이라는 고유명사--특정 언어와 별 관계가 없는--가 더 중요한데 굳이 일일이 외국어 번역을 할 필요도 없는 것이고..
차라리 공항 철도가 4개 국어를 다 방송하는 건 말이 된다. 거기는 음성뿐만 아니라 LED 화면 자막까지 4개 국어로 해 주고 있으니 말이다. 더구나 역 간격도 일반 지하철보다는 훨씬 길기 때문에, 4개 국어 방송을 내보낼 시간적 여유도 되니 말이다.

Posted by 사무엘

2010/04/28 18:26 2010/04/28 18:26
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/255

※ 2000

일반 사용자를 대상으로 NT 커널과 9x 계열의 통합을 야심차게 기획했던 운영체제이다.
하지만 윈도우 디렉터리의 이름은 여전히 Windows가 아닌 WinNT였고, 특이하게도 마우스 포인터의 이동 자취(trail)를 남기는 기능이 없었다. 9x 계열은 말할 것도 없고 구닥다리 윈도우 3.1조차 갖추고 있는 기능인데 NT에서만 원래 없었던가? 물론 XP부터는 이 기능이 있다.
탐색기에서 wav/mp3을 클릭 후 바로 재생이 가능하던 유일한 운영체제이다.

그리고 2000부터 GUI의 표준 색상이 약간 바뀌었다. 그저 RGB(192,192,192)이던 회색은 살짝 더 누르스름하게 바뀌고, 파랑은 좀더 어둡고 군청색에 가깝게 바뀌었다.
그런데 유독 윈도우 2000만.. 스타크래프트 같은 256색 전체 화면에 들어갔다가 나오면 그 파란색이 예전의 덜 어두운 색으로 돌아가는 신경 쓰이는 버그가 있었다. 이 역시 ME라든가 XP 이후부터는 전혀 발생하지 않으며 윈도우 2000만의 문제. 후대의 추가 최신 업데이트까지 다 받으면 어찌 될지 모르지만, 아무튼 SP4까지 가도록 이 문제는 고쳐지지 않았다. 2000만의 고질병으로 기록될 듯.

(이해를 돕기 위해 스크린샷을 첨부하자면, '위'가 '아래'로 바뀐다는 뜻이다. RGB(10,36,106)이 RGB(0,0,128)로 변경. 본인에게는 정말 바로 티가 나고 아주 거슬리는 버그였던 반면, 저 버그에 대해서 공감하는 사람은 주변에서 지금까지 전혀 보지 못했다. 윈도우 2000 쓰면서 스타도 띄워 본 적 없나??)

사용자 삽입 이미지

※ XP

1. 유저 인터페이스가 파격적으로 많이 바뀌었다 보니 초창기 SP0은 별 특이한 버그가 많았다.
스트링을 내장하고 있지 않은 리스트박스나 콤보박스는 LB_ADDSTRING 내지 CB_ADDSTRING 메시지로 아이템을 추가할 때 당연히 string을 NULL로 지정해도 괜찮은데, 새로운 비주얼 스타일(테마)이 적용된 컨트롤은 저렇게 하면 프로그램이 죽는 어이없는 버그가 있었다. -_-;; (비주얼 스타일 없는 옛날 컨트롤은 문제 없음)

95부터 2000/ME까지 아무 탈 없던 코드가 유독 XP에서만 문제를 일으킨 것. 과거 <날개셋> 한글 입력기 2~3.x 시절에 윈도우 XP (sp0)에서 일부 제어판 UI가 뻗던 문제는 이 문제 때문이었다. 매우 황당한 버그이기 때문에 이 문제는 SP1에서 곧바로 고쳐졌다.

2. XP부터는 응답이 없이 죽은 윈도우는 대책 없이 배째라 있는 게 아니라, 최소한 창의 이동과 강제 닫기는 가능한 일명 고스트 윈도우를 그 프로그램의 원래 윈도우를 대체하여 잠시 보여주는 기능이 추가됐다. 그래, 만든 취지는 좋다.

그런데.. 최대화되어 있던 프로그램 창이 한동안 응답이 없어서 고스트 윈도우가 됐다가... 다시 돌아와서 깨어나면,
그 창의 최대화 이전의 위치와 크기가 사라지고 창의 최대화를 해제해도 창 크기 자체가 최대화나 마찬가지인 상태로 남는 버그가 있었다. -_-
이 문제 역시 SP1을 전후한 시기에 고쳐졌다.

3. SP0은 무선 인터넷을 좀 하다 보면 lsass던가 뭐가 이상한 시스템 프로그램이 문제를 일으켜서 1분간 초 단위로 카운트다운을 한 후 운영체제가 재부팅되는 현상도 있었다. -_-;;
갑자기 그런 게 떠서 놀랐고, SP1만 설치해도 그 문제가 없어지는 것을 보고는 더 놀랐다. 도대체 SP0에서는 무슨 문제가 있었기에?

이외에 다른 사람들은 XP에서 시스템 차원에서 첫 도입된 TSF와 관련된 문제(ctfmon) 등 여러 버그를 찾아낸 듯하던데(해결책이라고 내놓은 게 '고급 텍스트 서비스 사용 안 함' ^^), 본인은 그런 건 모르겠고 저 세 가지 버그가 지금까지 기억에 남는다.
SP2는 저런 사소한 버그 해결 수준이 아니라 보안 관련 기능 추가가 즐비해서 단순 서비스 팩 같지가 않고,
SP3은 제대로 쓸 일도 없이 그 즈음에 비스타로 갈아타게 돼서 잘 모르겠다. SP2 정도만 해도 사실 상당히 안정화가 돼 있으니까.

※ 비스타

굉장히 오랜만에 출시된 만큼 엄청나게 높아진 사양, 그리고 디폴트로 적용돼 있는 UAC (사용자 계정 컨트롤) 때문에 뭇매도 많이 맞았다. 하지만 비스타는 객관적으로 상당히 잘 만든 OS이며, 7에 비해서 그 정도로 평가절하될 품질은 결코 아니다. 윈도우 98이 단순히 95+IE4가 결코 아닌 것과 같은 이치이다.

본인은 language bar (TSF 도구모음줄, 입력 상태 표시줄)를 task bar(작업 표시줄) 내부에 포함(embed, minimize)시키는 게 아니라 바탕화면에 동동 띄워 놓고 지낸다.
그런데 유일하게 비스타에서만 구경한 버그로는.. 응용 프로그램을 좀 사용하다 보면 이 language bar가 사라져 버리고 아마 내 기억이 맞다면 한글 입력도 안 되는 것.
내 컴만 그런가.. 왜 그런지 좀 성가시고 불편했다. 윈도우 시스템 디렉터리로 가서 ctfmon.exe를 재실행하면 사라졌던 language bar가 살아났다.

이것도 요즘은 구경을 안 하는 걸 보니, 다행히 서비스 팩을 설치하는 과정에서 고쳐진 것 같다.
엑셀 2007에서 유명하던 65535 곱셈 버그가 생각난다.
예전에 MS의 정책은 SP n은 SP n-1을 다 포함하는 형태였던지라, 최신 서비스 팩 하나만 갖고 있으면 됐다. 비주얼 C++ 6이라든가 윈도우 NT는 패키지 프로그램을 설치 후 최신 SP인 SP6만 깔면 끝이었던 것.

그런데 윈도우 비스타부터는 SP2를 깔려면 먼저 SP1부터 깔아야 한다. 매번 꽤 오래 시스템 파일 고치고 재부팅하고.. 불편하더라.
그래도.. 본인은 보안 업데이트는 귀찮아하는 편이지만, 서비스 팩은 그때 그때 깔 필요가 있다는 걸 체험 중. 왜냐하면 내가 현실적으로 직접 겪는 버그가 서비스 팩을 통해 곧장 해결된 경우를 꽤 자주 겪었기 때문이다.
듣기로는 비주얼 스튜디오 2010을 설치하려면 비스타조차도 SP1 이상이 필요하다.

아 그리고.. 윈도우 비스타 SP0은 인증 기간이 끝나면 대놓고 작동이 완전히 맘춰 버리는 유일한 운영체제이기도 했다. 기능 제한 모드가 되어, 인증을 받게 인터넷 접속이 가능한 웹브라우저 하나만 달랑 뜨고 다른 모든 기능을 사용할 수 없었다. 이 때문에 항의가 빗발쳤는지 SP1부터는 바로 사라지고 이는 후속작인 윈도우 7도 마찬가지. 화면이 주기적으로 까맣게 변하고 '이 제품은 정품이 아닙니다' 자막만 뜰 뿐, 동작 자체는 한다.

※ 7

콘솔에서, 한글을 조합 중이다가 비조합 문자를 “IME 차원에서” 삽입하면 조합 중이던 문자가 덧나는 버그가 있다. 이건 <날개셋> 문제가 아니라 MS IME에서도 나타나는 운영체제의 버그이다.
가령, "다"를 조합 중에 마침표를 누르면 "다."가 아니라 "다다."가 되는 것.

MS IME의 경우 두벌식일 때는 발생하지 않는다. 두벌식은 A~Z 사이에 배당된 한글 글쇠만 IME 차원에서 삽입하고 여타 숫자나 기호는 영문 자판과 동일한 방식으로 별다른 터치 없이 응용 프로그램으로 보내기 때문이다.
과거에 포트리스 space 버그를 비롯해서 MS IME가 유독 세벌식 자판에서만 발생하는 버그가 심심찮게 발견됐던 이유는 이런 동작 방식의 차이 때문이다. 세벌식은 아는 사람도 쓰는 사람도 거의 없다 보니 버그 발견이나 수정도 금방 금방 되지 않을 것이고.. -_-

이제 문자 입력 쪽 기능은 비스타 이후로 좀 안정화가 돼 있길 바랐건만, 또 뭘 건드려서 저런 버그가 생겼는지 모르겠다. SP1에서라도 당장 고쳐져 있길 기대한다.

Posted by 사무엘

2010/04/27 12:51 2010/04/27 12:51
,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/254

과학의 날, 과학 노래

1. 과학 하는 마음으로 능률 있게 일하고
사람마다 손에 손에 한 가지씩 기술 익혀
부지런한 하루하루 소복소복 부는 살림
세상에 으뜸 가는 복된 나라 이루세

2. 과학으로 이치 찾아 새로운 것 발명하고
겨레의 슬기 모아 산업 크게 일으켜서
천 불 소득 백 억 수출 무럭무럭 크는 국력
세상에 으뜸 가는 힘 센 나라 이루세

3. 과학 하는 국민으로 기술 가진 국민으로
살림살이 늘려 가고 산업 크게 일으키면
나라의 힘 용솟음쳐 다가오는 평화 통일
세상에 으뜸 가는 민족 중흥 이루세


이 노래 아시는 분?
1970년대에 제정된 과학의 (날) 노래이다.
정말 "새벽종이 울렸네 새 아침이 밝았네" 만만찮게 그 시절 냄새가 아주 노골적으로 난다.

(박 정희는 교사 출신이고 음악· 미술 같은 예능에도 조예가 깊은 사람이었다. 본인은 개인적으로 <새마을 노래>-_-는 누구 대필이 아니라 그 사람이 진짜로 스스로 작사· 작곡했을 가능성이 높다고 생각한다.)

3절의 '민족 중흥' 하면 생각나는 거 없는지?
국민 교육 헌장에서 말고는 요즘 도무지 찾을 수가 없는 단어인데, 그때 '그분'이 저 표현을 정말 좋아했던 것 같다.
'국민 소득 1천 달러, 수출 100억 달러' 이런 가사는 정말, 철도의 노래로 치면 '지축을 흔드는 우렁찬 소리' 급의 옛날 추억이 돼 있다.

4월 19일은 우리나라에서 4 19 혁명일일 뿐만 아니라 찰스 다윈이 세상을 떠난 날이다.
(다른 훌륭한 과학자도 많은데 왜 하필 다윈이야.. -_-)
우리나라에서 과학의 날은 일제 강점기이던 1934년에 다윈의 기일을 기려 처음 시작됐다.
소파 방 정환 선생이 제정한 어린이날보다 약 10년 정도 늦게 시작된 것이다.
그러다가 과학 기술처가 발족된 4월 21일을 기려, 1968년부터 과학의 날이 재제정되었다. 참고로 국민 교육 헌장은 1968년 12월에 공표되었다.

본인은 저런 노래를 어떻게 아냐고?
엄청 어렸을 때 옛날 국민(초등)학교 음악 테이프에서 들었던 노래들은, 죽을 때까지 안 잊어버리고 기억하고 있어서이다. 머릿속 시스템 디렉터리에 known DLL로 등록됐다. ㅋㅋㅋㅋ
딱 초등학교에 입학할 때 이미 '읍니다'는 '습니다'로 바뀌어 있었고 국민 교육 헌장도 다 삭제되었지만, 그렇게 바뀌기 전의 교과서들을 본 기억은 있다. 정말 엄청난 옛날이 됐다.

본인은 딱히 수꼴 성향이거나 박통교-_- 신자는 아니다.
그러나 그 시절은, 이공계 과학 기술자가 "지금보다야" 정말 대접 받았으며, 긍지를 갖고서 마음껏 국가를 위해 일하던 시절이었을 거라고 생각한다.
그 반면 지금은? 현직 과학자들부터가 "내 자식 새끼는 절대로 이공계에 진학 안 시킬 거다" 그러는 시절이지 않은가!

  "그 어려운 살림에서도 박대통령은 과학 기술자들에게 파격적인 대우를 해줬다. 틈만 나면 과학기술자들 곁을 찾았다. 과로로 숨진 과학자들도 여러 명이나 됐다. 대전에 있는 국방과학연구소에는 그가 며칠씩 머물던 방이 하나 있었다. 그 방은 과학기술에 대한 그의 일선 지휘소였다. 그러나 그가 가고 난 지금까지 그 방을 찾는 사람은 아무도 없었다. 나머지 대통령들에겐 입으로만 과학이 중요했다."

아무리 지 만원 박사의 정치 성향이 싫다 하더라도 위의 내용만은 인정할 수밖에 없을 것이다.
특히 국방 과학 연구소는 정말 사기에 가까운 업적으로 지금까지 우리나라를 먹여 살리고 지키고 있는 곳 중 하나이다. 작년에도 과로로 순직한 분이 있었다!
나라가 잘 돌아가고 있을 때는 의료· 법조· 금융 같은 제로썸 산업 종사자가 아니라, 기술자가 늘 대접을 받았다.

  또 예루살렘에서 솜씨 있는 사람들로 하여금 기계(engine)들을 만들게 하여 망대와 보루 위에 두고 그것들로 화살과 큰 돌을 쏘게 하였더라. 그의 이름이 멀리 퍼졌으니 그가 놀랍게 도움을 받아 마침내 강하게 되었더라. (대하 26:15)

성경에서 역대기하 26장의 웃시야 왕의 업적을 읽어보면 정말 우리나라가 농업 개량을 하고 경제 개발하고 국방을 강화하던 1960~70년대 시절이 오버랩된다. 웃시야 왕은 교만으로 인해 비참한 최후를 맞이한 것도 박통과 일치하는 것 같다.

본인은 요즘 우리나라가 중산층이 몰락하고 빈부 격차 양극화가 심해지고 있다고 성토하는 사람에게 이렇게 묻는다. 그럼 이 땅에 중산층이 생기긴 언제 생겼냐고 말이다.
과학과 관련된 노래로 옛날에 드라마 카이스트 주제가가 생각나고, 대전 엑스포 주제가도 생각난다. 코리아나는 영 건전 가요 컨셉인 것 같다. 88 올림픽 주제가에 비해서 그리 잘 알려져 있지 않은 후자의 가사를 소개하며 글을 맺는다.


푸른 산들은 우리에게 말하네 고운 햇살 뿌려 달라고
이제 모두가 슬기로운 손길로 밝은 내일 꾸며 가 보자
아름다운 마음 마음 모여서 사랑으로 보살펴 주면
꿈이라고 생각했던 일들이 우리 앞에 펼쳐진다네 그 날은

우리 모두가 힘을 한데 모아서 끊임없이 달려 가 보자
하루하루가 다시 열릴 때마다 놀랄 일이 너무도 많아
우주 안에 감추어진 비밀을 차근차근 벗겨 가 보면
꿈이라고 생각했던 일들이 우리 앞에 펼쳐진다네 그 날은

그 날은 찾아오리라 그 날은 찾아오리라
미래의 물결 속에서 그 날은 찾아오리라 그 날은, 그 날은

Posted by 사무엘

2010/04/23 22:47 2010/04/23 22:47
, ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/252

컴퓨터 구조를 공부하면서 배우는 기본 개념 중 하나는, ‘컴퓨터 내부에서 숫자가 표현되는 원리’이다.
부호 있는 정수는 소위 말하는 ‘2의 보수’ 형태로 표현되는데, 이것은 모든 비트가 1인 숫자는 -1이 되는 형태이다. 이런 방식을 쓰는 이유는 연산 회로를 설계할 때, 뺄셈을 덧셈의 변형만으로 매우 손쉽게 구현할 수 있는 체계이기 때문이다.

베이직 언어는 다른 언어들과는 달리 TRUE의 값이 -1인데, 그 이유가 바로 이런 컴퓨터의 구조와 관련이 있다. 베이직은 비트 연산자와 논리 연산자의 구분이 없기 때문이다.
0 아니면 1밖에 모르는 디지털 컴퓨터는 연속이나 무한 같은 개념을 표현할 수 없다. 숫자도 정수만 다루는 데 익숙하다. 그러나 현실 세계에서 발생하는 문제를 해결하려면 소숫점이 동반된 실수를 다뤄야 할 일도 매우 자주 발생한다.

소수를 표현하는 가장 간단한 방법은 소위 ‘고정소수점’이다. 가령 32비트 고정소수점의 경우, 정수와 완전히 똑같은 방법으로 숫자를 표현하되 실제로는 그 수의 의미를 정수를 16비트 크기만큼(65536) 나눈 것으로 인식하는 것이다. 즉, 수의 정밀도만 1이 아닌 1/65536으로 기계적으로 높아지는 셈.

고정소수점은 일단 덧셈· 뺄셈· 비교 연산을 정수와 완전히 동일한 방식으로 할 수 있어서 처리 속도가 매우 빠르며, 곱셈과 나눗셈을 할 때만 약간 주의해서 자릿수 정돈을 하면 되니 편하다. 실제로 일부 벡터 그래픽이나 글꼴 쪽 분야에서는 이런 고정소수점 방식이 잘 쓰이고 있다. 그러나 표현 가능한 수의 범위가 매우 심각하게 제한을 받기 때문에 범용성은 떨어진다.

자리수의 제약을 받지 않고 소수점을 좀더 자유롭게 표현하려면, 유효숫자와 자릿수를 따로 둘 필요가 있다. 그게 훨씬 더 실용적이다. 부동(floating)이라는 개념이 여기에서서 나왔다. 제일 큰 자리수의 숫자가 무엇이며 그 뒤에 0이 몇 개 붙느냐가 중요한 것이다.

이런 체계에서는 10.5에서 0.5는 제대로 표현할 수 있지만, 10000000.5에서 0.5는 손실될 가능성이 커진다. 그리고 한 숫자를 결국 두 수의 조합으로 표현해야 하므로, 각종 연산이 단순 정수보다 훨씬 더 느리고 힘들어진다.

옛날에는 이런 부동소수점 계산을 하드웨어 회로 차원에서 바로 해 주는 코(보조)프로세서가 별도로 존재했다. fdiv, fmul 같은 인스트럭션. 심지어는 제곱근이나 삼각함수 값까지 바로 구하는 명령이 있다!
하지만 시중에는 그런 게 없는 컴퓨터도 있다는 얘기이기 때문에, 1990년대에 상업용으로 쓰이던 어지간한 컴파일러들을 보면 소프트웨어적으로 부동소수점 계산을 흉내 내는(엄청 느리지만-_-) 코드를 추가할지를 지정하는 옵션도 있었다.

그런데 부동소수점을 표현하는 방식 자체가 통일돼 있어야 그 기준에 따라 코프로세서를 만들든지 말든지 할 수 있을 것이다. 그 표준 규격이 바로 IEEE754이다. 1985년에 제정되었다.

이 규격은 좀 정밀도가 떨어지지만 처리 속도가 더 빠른 32비트와, 용량이 넉넉하지만 역시 속도의 압박이 있는 64비트로 나뉜다. CPU 단위가 16비트이고 부동소수점을 소프트웨어적으로 처리하는 게 보편적이던 옛날에는, 아예 컴파일러 재량으로 소프트웨어적으로 구현한 48비트(6바이트-_-.. 파스칼에서 Real) 실수와 80비트(C/C++에서 long double) 실수도 존재하였으나 지금은 완전히 흑역사가 되었다. 요즘은 화면 픽셀 크기도 24비트는 존재하지 않으며 32비트이다. 죄다 컴퓨터가 처리하기 편한 단위로 그냥 확장된 듯하다.

제일 간단하게 말하자면, 32비트 실수에서는 1비트는 이 수의 부호를, 다음 8비트는 지수를, 다음 나머지 23비트는 유효숫자를 나타낸다. 64비트 실수에서는 그 비율이 1:11:52이다.
컴퓨터가 사용하는 부동소수점의 지수의 밑은 너무 당연한 말이지만 10이 아니라 2이다. 따라서 2의 거듭제곱의 역수가 아닌 모든 소수들은 끝자리가 잘린 ‘순환소수’가 된다! 0.25, 0.125, 0.5 같은 수가 아닌 다른 모든 수들.. 0.1, 0.2, 0.3 이런 것들은 화면에서는 적당하게 근사되어 표현되었다 할지라도 실제로는 그 수의 100% 정확한 형태로 저장되지 않은 셈이다. 부동소수점의 한계를 분명히 알고 있어야 한다.

어쨌거나.. 2^23과 2^52에다 base가 10인 로그를 씌워 보면 32비트 실수의 유효숫자 정밀도는 약 7자리, 그리고 64비트 실수의 정밀도는 약 15자리라는 걸 알 수 있다. 그리고 표현할 수 있는 자리수의 범위는 32비트는 약 38자리, 그리고 후자는 약 308자리이다(비트가 3개 더 늘어서 2^3인 8배가 더 늘었으므로). 소수점 밑으로도 그만치 내려갈 수 있다.

까놓고 말해 이런 공용체를 통해 부동소수점을 쉽게 해부할 수 있다.

union REAL {
   float fValue;
   struct {
      unsigned sign: 1; //부호
      unsigned expo: 8; //지수부
      unsigned mantissa: 23; //가수부
   };
};

공용체와 비트 필드가 존재하는 C/C++ 만만세. ㄲㄲ
단, 우리가 쓰는 인텔 CPU는 little endian이므로 sign, expo, mantissa 순이 아니라 반대로 mantissa, expo, sign으로 멤버 순서만 바꿔 주면 된다. 쉽죠?

그런데 지수부와 가수부 사이에 아무런 제약을 가하지 않을 경우 동일한 숫자를 여러 방법으로 표현할 수 있게 되어 문제가 생긴다. 4를 2의 2승, 4의 1승 이런 식으로 표현하듯이 말이다. 그래서 IEEE754는 가수부는 가장 큰 자리수의 비트값이 무조건 1인 것만 인정하게 하고 그 1은 명시적인 표기를 생략했다. 이를 ‘정규화’된 형태라고 한다.

거두절미하고, 32비트 부동소수점에서 구조체의 각 멤버로부터 부동소수점 값을 다시 얻어 오는 식은 다음과 같으므로 참고하자. 식에서 23과 24는 가수부의 자릿수 23비트와 관계가 있으며, 126은 지수부의 크기 8과 관계가 있다. 2의 8-1승보다 2 더 작은 값이다. 1<<23이 바로 생략된 최대 자리수인 셈이다.
그저 의미를 알 수 없는 블랙박스 같던 부동소수점이 좀더 친근하게 와 닿을 것이다.

pow(2.0, (double)( (int)a.expo-24-126))* ((1<<23)|a.mantissa) * (a.sign ? -1:1)

IEEE754에는 이외에도 무한대를 표현하거나 불능을 뜻하는 규격이 있다. 정수를 0으로 나누면 CPU 차원에서 바로 exception이 일어나지만 부동소수점은 에러는 안 나고 저런 특수한 숫자가 돌아온다.
또한 정규화를 해서 자리수를 강제로 늘리는 바람에 표현할 수 없게 된 일부 극히 작은 수를 별도로 표현하기 위해 내부적으로 심지어 ‘고정소수점’ 방식을 임시로 사용하는 규정조차 갖추고 있다. 마치 퀵 정렬이 작은 구간에서는 삽입 정렬을 사용하기도 하는 것처럼 말이다. 이에 대한 더 이상의 자세한 설명은 생략하겠다.

참고로,
1. IEEE754 부동소수점에는 구조적인 한계로 인해 0이 +0과 -0 이렇게 두 개 존재한다.
2. 역사상 최초의 전자식 컴퓨터로 일컬어지는(논란의 여지는 좀 있지만) 에니악은 10진법을 사용했다! 전자 신호 4비트(=16)로 10진법 숫자 하나를 표현했을 것이고 매우 비효율적으로 동작했을 것이다. 하지만 그 당시엔 이 기계로 탄도 계산도 하고 풍동 실험도 하고 심지어 일기 예보도 했었다.

Posted by 사무엘

2010/04/22 22:53 2010/04/22 22:53
, ,
Response
No Trackback , 7 Comments
RSS :
http://moogi.new21.org/tc/rss/response/251

<날개셋> 편집기를 오래 써 온 분들은 아마 아실 겁니다. 찾기/바꾸기 대화상자에 아주 교묘한 버그가 있습니다.
글을 쓰다가 Ctrl+F 또는 Ctrl+H로 이 대화상자를 한 수십 번 꺼내다 보면
정말 가끔, 아주 random한 확률로 엉뚱하게 explorer.exe가 죽거나, 편집기 프로그램이 죽거나 응답 불능 상태에 빠집니다. 윈도우 XP부터 비스타에서 모두 이런 증상이 나타나는 걸 확인했습니다. 에러 대화상자를 살펴보면 comctl32.dll이 뻗었다고 나옵니다.

이건 저도 원인을 알 수 없고 참 괴이하기 그지없는 버그입니다.
딱 원하는 때에 맞춰 재연은 절대로 할 수 없지만, 그래도 어디서나 언젠가는 100% 반드시 나타난다고 보장할 수 있는 현상이었지요.
발생 조건에 관한 한 최악의 버그입니다. 저는 무려 <날개셋> 3.x 시절부터 이것에 대해 알고 있었지만 디버깅할 엄두를 못 내고 있었습니다.

찾기/바꾸기 대화상자가 <날개셋> 편집기의 여느 대화상자들과 다른 점은 '탭 컨트롤'을 써서 찾기와 바꾸기 기능을 구분하고 있다는 점입니다. 혹시 이게 문제인가 싶어서 이번 기회에 아예 대화상자의 디자인을 바꿔 버렸습니다. 물론 5.53에는 아직 이게 적용이 안 돼 있고요.
5.53 이후로 다음 버전이 언제 나오게 될지 모르겠지만, 이렇게 하니까 이제는 저 문제가 없어졌는지 최소 몇 달간 살펴볼 예정입니다.

Posted by 사무엘

2010/04/19 07:35 2010/04/19 07:35
Response
No Trackback , a comment
RSS :
http://moogi.new21.org/tc/rss/response/249

철도에 고속철이 있다면 여객 항공기에는 초음속기가 있습니다. (정말 적절한 비유 ㅋㅋㅋㅋ)

1.

1903년이던가, 미국의 라이트 형제가 최초로 동력으로 움직이는 항공기를 발명한 후,
항공기는 1차, 2차 세계대전을 거치면서 전투기로도 등장하고 이내 여객용으로 가히 지구촌 시대를 열었습니다.
우리가 이용하는 대부분의 여객기는 최고 속도 순항 상태일 때 시속 850~900km (마하 0.9)쯤 되는 아음속기입니다. 이 정도로도 육지에서는 도저히 경험할 수 없는 빠른 속도이며, 사실 바람을 잘 탈 때면 아음속기도 시속 1200~1300에 도달해서 잠시 초음속으로 날기도 합니다. 그러나 속도에 대한 열망은 그것으로 모자라 초음속기의 개발을 부채질했습니다.

물론 자동차 중에도 초음속 자동차라는 게 있어서 주로 사막에서 시범 운행한 경우가 있습니다.
하지만 실용성은 거의 없죠. 그리고 그런 차들은 엔진도 일반적인 자동차의 4행정 기관이 아니라 제트 엔진을 쓰기 때문에 배기가스 배출, 연료 소모도 장난이 아닙니다. 여객 항공기는 대개 터보 팬 엔진을 쓰죠.

철도를 움직이는 핵심 동력원으로는 지하철과 고속철 모두 전기가 각광을 받고 있지만 비행기의 동력원은 역시 기름입니다. 그렇다고 해서 디젤-전기 방식은 아니고요. 항공유는 경유-중유 수준의 묵직한 디젤유는 아니고 휘발유에서 등유 사이뻘 되는 등급으로 알고 있습니다. 단지, 경주용 자동차용 연료에다 그러는 것처럼 옥탄가를 더욱 강화하고, 특히 영하 수십 도에 달하는 구간에서도 얼지 않도록 부동액 성분도 첨가된다고 합니다.

오늘날 실용적으로 운행되는 고속철들이 최고 시속 250~300km대입니다. 하지만 비행기는 활주로를 한창 지나서 날아오르기 직전에 이미 시속 300km대로 달리게 됩니다. 열차가 자꾸 자주 정차하는 건 싫지만 항공기가 이착륙하는 건 신나고 재미있습니다.

항공기는 고도의 유체역학 원리에 따라서 하늘로 뜨게 됩니다. 당연한 말이지만, 양 옆으로 날개도 폼으로 있는 게 아니라 치밀한 설계에 의해 넣은 것이죠. 그런 비행기들은 지구와 같은 공기가 없는 곳에서는 연료를 연소시킬 수 없기 때문에 날 수 없기도 하지만, 양력을 발생시킬 수 없어서 더욱 뜰 수 없습니다.
또한 반대로 말하면 우주선들은 어차피 지구 대기권을 나는 항공기와는 다른 방식으로 운항하기 때문에 날개가 필요 없습니다.

2.

전투기야 우리나라도 초음속기 개발에 성공했으니 더 말이 필요없지만,
초음속 여객기 하면 역시 영국과 프랑스 합작으로 개발되었던 콩코드가 거의 유일합니다. 잘 알다시피 음속의 2배를 조금 넘겼지요.
사실, 콩코드가 등장하기 전에 미국과 소련은 냉전 구도 하에 우주 개발 경쟁만 한 게 아니라 초음속 여객기 연구도 앞장서서 했습니다. 하지만 미국은 그런 건 만들어 봐야 경제성이 없다는 판단 하에 일찌감치 연구를 포기했습니다. 그 대신 아음속 여객기의 덩치를 더욱 키우는 연구를 계속했죠.

그 반면 소련은 콩코드보다도 먼저 사실, 세계 최초의 초음속기를 만들어내기는 했지만 상용화하지는 못했습니다. 이런 와중에 영국과 프랑스가 유럽의 항공 기술의 자존심을 걸고 막대한 비용을 들여서 공동 연구를 한 끝에 콩코드를 만들어 내고, 적자까지 감수하면서 나름 20년이 넘는 세월 동안 운행을 한 것입니다. 대서양을 건너 런던· 파리에서 미국 뉴욕 사이를 왕래했습니다.

콩코드가 첫 비행에 성공한 것은 1969년 3월로, 인간이 최초로 달에 가는 데 성공한 아폴로 11호 발사의 4개월 남짓 전입니다.
콩코드는 빠른 속도를 내기 위해서 많은 것을 희생해야 했습니다.
폭이 작고 복도가 매우 좁아져서 한 줄당 좌석이 기차나 버스 수준인 2x2입니다. (우왕!)
만석일 때 100수십 명 남짓밖에 탈 수 없어서 이는 결국 한 사람당 매우 비싼 운임으로 연결됩니다. 2003년경에 대서양 한번 건너는 편도 운임이 한국 돈으로 거의 900만~1천만 원.. 일반 아음속 항공기 일반실 운임의 10배가 넘었다고 합니다.

어마어마한 동력을 내야 하기 때문에 같은 거리를 날아도 연료도 더 많이 들고, 이륙도 더 빨라야 하고 타이어에 걸리는 부담도 더 크고, 뜰 때 더 가파르게 하늘로 올라야 했다고 합니다. 거기에다 성층권의 오존층 파괴 문제, 소닉 붐 충격파, 자국 영공 내에서의 초음속 비행에 대한 규제 등, 골치 아픈 요인도 많았습니다.

끝으로 또 생각할 게 있습니다. 비행기가 하늘을 나는 상공은 영하 수십 도에 이르는 저온이지만, 그 정도로 빠르게 날면 공기와의 마찰 때문에 기체 역시 100~200도나 되는 온도로 달궈집니다. 우주선이 지구 대기권으로 재돌입할 때 시뻘겋게 열 받고 달아오르는 것과 같습니다. 그렇기 때문에 초음속기는 단순히 엔진의 출력만 강한 게 아니라 열에도 강해야 하고 마치 철도 레일이 여름에 늘어나는 것처럼 어느 정도 신축 현상에도 대비하여 설계되어야 합니다.

3.

그럼에도 불구하고 초음속 여객기의 위력은 정말 대단했습니다.
마하 2.2의 속도로 날면서 예전에 8시간 가까이 걸리던 런던-뉴욕을 고작 3시간 반대로 단축시켰기 때문입니다. 생긴 것도 학처럼 정말 우아하게 생겼죠.

이거 아십니까? 콩코드는 지구가 자전하면서 지표면이 돌아가는 속도보다도 더 빨리 이동하는 인류 최초의 교통수단이었습니다. (우주선이나 로켓은 아예 지구를 떠날 때 쓰는 물건이므로 논외로) 그래서 정오에 런던을 출발하면 현지 시각으로 오전 11시 30분에 뉴욕에 도착할 수 있었습니다.
이를 이용해 그때 인류 역사상 초유의 엽기적인 프로젝트가 진행되기도 했습니다.

1973년 6월 30일에 개기 일식이 일어날 때의 일이었습니다. 이런 사건은 지구상에서는 잘 해야 5~7분 남짓한 시간 동안밖에 관측할 수 없으며 사실 이것도 굉장히 운이 좋은 경우입니다. 그런데 지구의 자전 속도보다 더 빠른 비행기가 발명되었으니, 비행기로 달의 그림자를 쫓아가면서.. 일식 장면을 계속 관측하는 게 어떨까 하는 엉뚱한 생각!

과학자들은 일식을 가장 잘 볼 수 있는 경로를 치밀하게 계산해 놓은 후, 그 비싼 콩코드 비행기를 무려 전세 내서 기내에 온갖 측정 장비들을 설치했습니다. 덕분에 하늘에서 개기 일식을 무려 70분이 넘는 시간 동안 관측할 수 있었습니다. 그 해 10월 15일에 오일 쇼크가 터지기 100일 정도 전의 일이었죠.
http://sodyssey.egloos.com/2323422.

4.

그러나 초음속 여객기는 대중화하기에는 아직 시기상조였는지? 콩코드 역시 운영상의 어려움과 적자에 시달렸습니다. 자존심이 있는데 당장 운항을 중단할 수는 없고 좀 애물단지 계륵처럼 됐죠. 그렇게 시간은 흘러서 20세기가 막바지에 이르고 콩코드의 내구 연한 30년도 임박하기 시작했습니다.

그러던 차에 2000년 7월, 대형 사고가 터지고 말았습니다.
프랑스 파리의 드골 공항에서 이륙하던 콩코드 4590편.
이륙하는 과정에서, 직전 항공기가 이륙하면서 떨어뜨리고 간 금속띠를 밟으면서 타이어가 쫙~ 찢어져 터지고, 그 타이어 조각이 연료탱크를 파손했습니다.
비행기는 이미 시속 300km V1 속도를 넘어서서 이륙을 중단할 수 없는 상태가 돼 있었고, 기체 뒷부분이 불길에 휩싸인 채로 하늘로 떴습니다.

연료는 양 날개 내부에 담겨 있었는데 그게 다 홀랑 타 버리니 날개가 남아나질 못했죠. 곧바로 양력을 잃고 실속 상태. 조종이 불가능해진 비행기는 고도 100미터를 채 못 오르고 저공에서 빙빙 돌다가 추락해 버립니다.
화재 때문이었는지 탑승객 전원 사망.
최첨단 초음속기에다 25년 가까이 무사고를 자랑했던 호화 여객기 콩코드의 위상이 크게 흔들리게 되었습니다.
사고 원인을 추적한 과정이 정말 대단하더군요. 추리 소설을 읽는 기분이었습니다.
http://blog.naver.com/toysher?Redirect=Log&logNo=50007967386

이 사고를 계기로 콩코드는 안전 기준도 더욱 강화되었지만 슬슬 운행 중단으로 기울어 갔고,
2003년 10월엔 모든 콩코드기가 운항을 중단하고 현역에서 물러나게 됩니다.
간간히 뉴욕-도쿄 간 초음속기가 새로 개발 중이라고 몇 년 전부터 소식은 들어 왔지만 그게 언제 다시 실현될지는 모르겠습니다.

Posted by 사무엘

2010/04/16 12:35 2010/04/16 12:35
, , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/247

원에 대한 적분 외

원이란 2차원 공간상의 한 점에서 거리가 같은 점들의 집합으로 정의된다. 공간이 3차원으로 확장되면 구도 이와 같은 맥락으로 정의 가능하다.
이 정의에 따라, 먼저, 0..r 범위에서 반지름이 r인 사분원을 나타내는 방정식

  f(x) = sqrt(r^2 - x^2)

를 정의하자.
이 사분원의 호의 길이는 거리의 적분에 따라

  int(  sqrt( f'(x)^2 + 1 ) , x=0..r)

(f'(x)는 f(x)의 도함수. int는 짐작하듯이 0부터 r까지 x에 대한 정적분을 나타냄)
을 풀면 PI*r/2 가 된다. 사분원의 길이이므로 여기에다 4를 곱하면
반지름이 r인 원의 길이는 2*PI*r이 나온다.
위의 적분식에서 1은 당연한 말이지만 적분변수가 약분되어 1이 된 것이며, 그걸 역시 제곱한 값이기도 하다. 괜히 더해진 게 아니다. ^^;;

넓이는 그냥 f(x)를 적분하면 바로 구해진다.

  int( f(x), x=0..r)

의 값은 PI*r^2 /4 가 되고, 역시 4를 곱하면 반지름이 r인 원의 넓이는 PI*r^2이 된다. 적분을 실제로 풀기 위해서는 치환 적분 기법이 필요하다.

이제 3차원 세계로 가서 구의 부피를 구하면 어떨까?
반구의 단면은 역시 0부터 r까지 반지름 자체가 원의 방정식과 같은 무수한 원으로 이루어져 있으며 이것들을 적분하면 부피를 구할 수 있다. 어렵지 않다. 즉, 원의 넓이 PI*r^2에서 r 대신에 f(x)를 넣으면 된다는 소리.

  int( f(x)*f(x)*PI, x=0..r)

의 값은 2/3 * PI * r^3이 된다. 반구의 부피이므로 이것에다 2를 곱하면 4/3 * PI * r^3이 바로 반지름이 r인 구의 부피이다.

마지막으로 구의 겉넓이를 구해 보자.
여기서 사람들이 제일 많이 틀리는 게 뭐냐 하면, 넓이를 그대로 적분하면 부피가 되었듯이 원호 길이를 그대로 적분하면 겉넓이가 될 거라는 생각이다. 그런데 그렇게 하면 적분을 해석적으로 풀든, 심지어 100개 1000개로 구간을 아무리 많이 나눠서 컴퓨터로 계산을 해 봐도 정확한 값이 나오지 않는다! 실제값보다 더 작은 값이 나온다.

원의 넓이나 구의 부피처럼 각 구간에서의 함수값만이 중요하다면 구간 수를 무수히 늘림으로써 정확한 값으로 수렴이 가능하겠지만, 구의 겉넓이는 앞서 다뤘던 '길이'를 구하는 것과 일면 비슷한 개념이다. 내 자신의 값뿐만 아니라 인접한 구간과의 기울기라는 개념이 감안되어야만 정확한 적분값이 나온다.
그래서 2*PI*r뿐만 아니라 원호를 구할 때 쓰던 식이 첨가되어야 한다.

  int( 2*PI * f(x)* sqrt( f'(x)^2 + 1 ), x=0..r)

이 적분식의 값은 2*PI*r^2이 나오며, 역시 2를 곱하면 반지름이 r인 구의 겉넓이는 4*PI*r^2임을 알 수 있다.

덧붙이는 말

1. 1부터 100까지 일일이 덧셈을 할 필요가 없이 등차수열의 합을 구하는 식에 대입만 하면 100이 아니라 1000, 10000까지의 합도 손쉽게 구할 수 있듯.. 우리가 알고 있는 리만 적분도 굉장히 대단한 지식이다. 수천, 수만 개의 구간을 나눠서 일일이 함수값을 구하며 뺑이를 칠 필요 없이, 함수식의 부정적분을 구한 후 하한값과 상한값의 차이만 구하면 된다니, 놀랍지 않은가? 게다가 여기에다 부분 적분과 치환 적분의 위력까지 더해지면 초월 함수를 다루기도 더욱 수월해진다.

2. 사실 미분과 적분은 서로 다른 별개의 분야에서 출발했다. 접선 기울기하고 면적/부피는 언뜻 보기에 분야가 다른 것 같은데, 함수의 부정적분이 도함수의 역함수와 같다는 것이 증명되면서 미적분학이라는 한 학문이 태동한 것이다. 옛날엔 '극한이라는 걸 수학적으로 엄밀하게 정의하는 게 가능하나?' '이건 너무 사악한 사고방식이 아닌가?' 이런 걸 갖고 고민하던 시절이 있었다. 그저 기계적인 계산 테크닉(로피탈의 정리 같은. -_-)만 달달 외워서 점수 따기에는 이 분야는 너무나 깊이 생각하고 느껴야 할 게 많다. 본인 역시 학창 시절엔 그런 걸 별로 경험하지 못했다. 세상에 이런 개념을 처음 만든 사람은 무슨 생각으로 이런 걸 만들어냈을지를 곱씹어 보자.

3. 리만 제타 함수라는 게 있다. ζ(n)은 1/1^n + 1/2^n + 1/3^n ..... 의 극한이다. n=1인 경우에 속하는 조화 수열은 0에 수렴하지만, 그 합은 로그 스케일로 매우 느리게 발산-_-하긴 한다. (일반적으로 미분과 적분을 거치면 x의 지수가 1 늘어나거나 줄게 마련인데, 지수가 -1에 속하는 1/x은 부정적분이 예외적으로 생뚱맞은 ln x로.. =_=) 하긴, 숫자가 커질수록 소수의 개수도 로그 스케일급으로 발견되며 매우 드물어진다. 소수의 개수 역시 무한하다는 뜻이기도 하다. 숫자가 커질수록 졸라 찾기 힘들어지겠지만 말이다. -_-;;

이런 함수가 왜 근사한 이름까지 붙어 있는가 하면, n이 2 이상의 짝수일 때 ζ(n)의 값은 PI의 n승의 유리수배의 형태로 산출되기 때문이며, 더구나 이 함수는 소수의 분포와도 관계가 있기 때문이다. 이 엄청난 발견을 해 낸 사람은 불세출의 천재 수학자인 오일러이다. 특히 삼각함수의 테일러 전개와 방정식의 근의 관계를 이용하여, ζ(2) = PI^2 / 6 임을 최초로 알아내기도 했다. 따라서 그 수는 초월수라는 것 역시 덩달아 증명된 셈.

나는 증명을 뻔히 보고도 뭔 말인지 못 따라가겠던데, 사실 저것도 수학에서 가장 아름다운 방정식이라는 e^(PI*I) + 1 = 0만큼이나 그의 위대한 업적이 아닌가 생각한다. 파이, 삼각 함수, 루트, 해석학, 기하학, 복소수 등등등... 다 위로 올라가면 서로 구분이 없이 여기저기서 다 만난다는 뜻이다. 심하게 경이로운 사실이다!

Posted by 사무엘

2010/04/15 20:07 2010/04/15 20:07
, , ,
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/246

C++에서 A라는 클래스를 만들었다. 이 클래스는 앞으로 당신이 만들 거의 모든 클래스들이 상속 받을 아주 기본적이고 공통적인 기능을 갖추고 있다. COM으로 치면 IUnknown, MFC로 치면 CObject 같은 기능을 하는데, 여기서는 그 예로 자체적인 reference counting 기능을 내장하고 있다고 치자.

class A {
 int nRefCnt;
public:
 A(): nRefCnt(1) {}
 ~A() {}
 int AddRef() { return ++nRefCnt; }
 int Release() { int nt=--nRefCnt; if(nt==0) delete this; return nt; }
};

이제 당신은 A로부터 상속 받은 여러 클래스들을 만든다.

class B: public A {
public:
 int nAddVal;
 B(): nAddVal(2) {}
};

class C: public A {
public:
 int nExitVal;
 C(): nExitVal(3) {}
};

그런데 C++에는 다중 상속이라는 게 존재한다.
어쩌다 보니, A의 자식 클래스들 중 서로 다른 클래스를 골라서 이들의 기능을 다 물려받은 클래스를 만들고 싶어진다. (욕심도 참 많다!)

class D: public B, public  C {
public:
 int nLast;
 D(): nLast(4) {}
};

여기서 문제가 생긴다.
이 경우, D는 B와 C의 기능을 물려받는 과정에서, B와 C가 공동으로 소유하는 A는 두 번 상속받게 된다.
32비트 기준으로 obj의 멤버 배열 순서는 대략 "1, 2, 1, 3, 4" 정도가 된다.

D obj;
obj.AddRef();

이 코드의 실행 결과는 어떻게 될까?
고민할 필요 없다. 이 코드는 컴파일 자체가 되지 않을 테니 말이다. =_=
D라는 클래스에는 A의 nRefCnt라는 멤버 자체가 둘 존재한다.
그렇기 때문에 B 쪽에 속하는 nRefCnt를 건드릴지, C 쪽에 속하는 nRefCnt를 건드릴지 판단할 수 없어서 컴파일러는 모호성 오류를 일으키는 것이다.
클래스 가계도는 보통 tree 구조가 되는데 이 경우 엄밀히 말하면 cycle이 존재하게 된다. 이 cycle을 일명 '죽음의 다이아몬드'라고 부른다.

obj.B::AddRef() 내지 obj.C::AddRef()라고 구문을 바꾸면 컴파일 에러 자체는 없앨 수 있다.
그러나 이것은 미봉책일 뿐이지 문제를 본질적으로 해결하는 방법은 아닐 것이다.
이건 클래스 B와 C가 아무 공통분모 없이, 우연히 AddRef라는 껍데기만 동일하고 의미는 완전히 다른 함수를 제각기 갖고 있는 것과 다를 게 없는 상황이다.
근본적으로는 D라는 클래스는 비록 B와 C의 기능을 동시에 상속 받았더라도 A는 단 한 번만 상속 받게 하는 방법이 있어야 한다. 그게 가능할까?

그래서 C++은 '가상 상속'이라는 걸 제공한다.
일반적으로 B라는 클래스가 A라는 클래스로부터 상속을 받았다면, B라는 클래스는 내부적으로 A의 몸체 뒤에 자기 몸체가 덧붙는다. 따라서 B 클래스의 오프셋과 A 클래스의 오프셋 사이의 간격은 컴파일 시간 때 딱 결정이 되어 버리며 언제나 고정 불변이다.

그런데 B가 A를 상속 받으면서 A를 '가상'으로 상속하면, B 클래스로부터 A 클래스의 오프셋은 자기가 별도의 내부 멤버로 갖고 있게 되며, 컴파일 시점이 아니라 실행 시점 때 동적으로 바뀔 수 있게 된다. 기반 클래스가 특수한 처리를 하는 게 아니라, 상속을 받고 싶어하는 자식 클래스가 상속을 특수한 방법으로 받아야 한다.
그래서 위의 네 클래스 A~D 중, 죽음의 다이아몬드를 해소하기 위해서는 B와 C가 A를 virtual로 상속 받게 하면 된다.

class B: virtual public A { ... };
class C: virtual public A { ... };

이 경우 B와 C는, 기반 클래스인 A가 자신과 메모리 상으로 굳이 연속적으로 이어져 있지 않더라도, B나 C 자신이 스스로 갖고 있는 부가 정보를 통해 기반 클래스인 A의 위치를 추적할 수 있다.

클래스 C만 갖고 생각하는 경우, 당연히 메모리 상으로는 A와 C가 바로 따를 것이고, C 내부에 있는 A의 포인터는 자기 바로 앞을 가리키고 있을 것이다.
하지만 클래스 D는 멤버가 ABCD와 같은 순으로 쫙 배열될 수 있으며, A와 C 사이에 B 같은 다른 클래스가 있을 수 있다. 그래도 B와 C가 A를 공유할 수 있게 된다. 공유를 하려고 이 지저분한 짓을 자처한 것이다.

자, 그럼 가상 기반 클래스의 구현 비용은 어느 정도 될까? C++에서

ptr->Function(a, b);

이라는 문장이 있고 Function이 virtual이 아닌 일반 클래스 멤버 함수라면, 위의 코드는 C 언어 문법으로 표현했을 때 대략

Function(ptr, a, b);

이 된다. 즉, this만 암묵적으로 추가되고 일반 함수와 완전히 똑같은 형태이다. 가장 간단하다.
하지만 Function이 가상 함수라면,

ptr->functbl->Function(ptr, a, b);

과 같은 꼴이 되고 오버헤드가 꽤 커진다. 우리 멤버가 가리키는 공용 가상 함수 테이블로 가서 거기서 함수 포인터를 참조하는 셈이다.
그렇다면 Function이 ptr이 가상으로 상속 받은 기반 클래스의 비가상 멤버 함수라면,

Function(ptr + ptr->baseptr, a, b);

정도. 가상 함수 정도는 아니지만 그래도 this 포인터의 위치 계산을 위해서 두세 개의 명령 오버헤드가 추가된다.
일단 다중 상속이라는 개념 자체가 컴파일러 문법상의 단순 형변환일 뿐이던 typecasting을 굉장히 복잡하게 만들었다는 점을 알 필요가 있다.

그럼 Function이 가상 상속에다가 가상 함수이기까지 하면 어떻게 될까?
그래도 functbl을 찾는데 오버헤드가 더해지지는 않는다. 어차피 각 클래스의 함수 테이블에는 자기가 지금까지 상속 받은 모든 클래스의 가상 함수들이 누적 기록되어 있기 때문에, 함수 호출을 위해 여러 테이블을 돌아다니지는 않는다.

참고로 A에 가상 함수가 있고 B와 C가 이를 제각기 오버라이드를 했는데 D가 B와 C를 동시에 상속 받고도 그 가상 함수를 또 오버라이드하지 않았다면, 컴파일 에러가 난다. B와 C 중 어느 장단에 맞춰 춤을 추리요? C++ 컴파일러는 그 정도 모호성은 자동으로 지적해 준다. C++ 컴파일러 만들기란 정말 힘들겠다는 생각이 들지 않는가?

가상 함수, 가상 상속, 멤버 함수 포인터... =_=;;
오늘날 프로그래밍 업계에서 다중 상속은 굉장히 지저분하고 흉악한 개념으로 간주되어 금기시되고 있다. C언어의 전처리기, 포인터와 더불어 현대의 프로그래밍 언어에서는 찾을 수 없는 면모가 되고 있다.
여러 클래스의 기능이 한꺼번에 필요하면, 무리하게 상속으로 해결하지 말고 해당 클래스 개체를 '멤버'로 가지는 쪽으로 가라는 것이다.

다중 상속이라든가 가상 상속이 골치아픈 게 결국은 데이터 멤버들의 오프셋 계산 때문이다. 하지만 가상 함수만 잔뜩 만드는 것은 그 클래스 자체가 아닌 함수 테이블의 덩치를 대신 키우는 것이고 클래스 자체는 가상 상속 같은 복잡한 테크닉을 필요로 하지 않기 때문에, 대다수 현대 객체 지향 언어들은 '인터페이스'라는 개념을 도입하여 이것으로 다중 상속의 기능을 어느 정도 대체하고 있다.
사실, C++의 각종 어려운 OOP 개념을 실제로 구현하는 데 비용이 얼마나 드는지를 잘 이해하고 있는 것만으로도 상당한 수준의 프로그래밍 내공을 쌓을 수 있다!

Posted by 사무엘

2010/04/14 17:19 2010/04/14 17:19
,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/245

« Previous : 1 : ... 190 : 191 : 192 : 193 : 194 : 195 : 196 : 197 : 198 : ... 215 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Site Stats

Total hits:
2679741
Today:
1825
Yesterday:
2484