아내와 나 같은 컴퓨터 공학을 전공하였지만, 아내는 연구소에 재직하게되면서, 코딩 실무보다는 설계와 관리쪽으로 치중하게 되었습니다. 비록 실무에서 코딩업무와 멀어졌다고는 하지만, 때론 설계가 잘 적용되었는지 코드를 직접 검토하여야 하기때문에, 가끔씩 저와 코드를 가지고 이야기 할때가 있습니다. 그러면 제가 우위에 서게되는 경우가 많았습니다.
그래서인지, 옛기억을 확실히 해야겠다며, 이번에 OOP 프로그램밍 교육을 신청하여 교육을 받기위해 서울에 머물게 되었습니다. 그런데, 첫날부터 아내로 부터 전화가 와서 숙제를 하는데, 이상하게 동작 하는데 도저히 모르겠다는 것이 었습니다.
다음과 같은 C++ standard library를 활용한 성적처리 프로그램인데, 국어점수로 정수인 99점을 입력하면 괜찮은데, 소수점인 99.5를 입력하면 무한 루프에 빠져버린다는 것입니다.
[code] int kor=-1, eng =-1, math =-1; int tmp; int wrong_score=true;
먼저 전체 소스를 살펴보면서 메모리 overflow가 있을만한 부분은 없는지 훓어보습니다. 대략 이상이 없어 보여 도대체 어떻다는 말인가 하고 프로그램을 실행해 보았습니다.
국어 점수 입력이 뜨자 99.5를 입력하고 엔터를 치니 그때부터 빠르게 ' 0 - 100 사이 값을 입력하세요!' 하는 문구가 수없이 화면을 지나가는 것이 보였습니다. 아 이렇다는 말이구나. 이후 국어점수로 일반 정수를 입력하면 이상 없이 잘 되는 것을 확인하였습니다.
물론 아내도 디버깅을 할 줄 압니다. 그렇지만, 고민하던 아내에게서 일단 내게로 공이 넘어왔으니, 나도 국어 점수 입력라인에 Break Point를 찍고 디버깅을 해보았습니다.
디버깅을 해보니 국어 점수로 99.5를 입력하면 99가 kor의 입력값으로 들어왔습니다. 음... int형이니까 .5가 무시된건가?, 그럼 잘 입력받는데 왜 그러지? 하고 다음 스텝들을 진행하였습니다.
그런데, 영어 점수를 입력받기 위한 cin >> eng; 라인에서 프로그램이 콘솔 입력을 대기하지 않고 그냥 지나처 버리는 것이었습니다. 응? eng 값을 보니 초기값인 -1을 유지하고 있었습니다.
일단 최초 의심은 국어점수 입력과정에서 메모리 overflow가 발생한게 아닐까 하는 것이었습니다. 그러나 국어점수를 기억하기위한 배열이나, Index Count등을 점검해 보았지만 이상이 없었습니다. 그래서, 아하 99.5와 같은 입력으로 인해 cin 객체의 상태에 뭔가 문제가 생겼구나 하는 생각에 이르렇습니다.
그렇다면 분명 초기화 하는 명령이 있을것 같은데....(학창 시절 외에 콘솔 프로그램을 거의 하지 않았으니 cin에 대한 기억이 거의 남아 있지 않았습니다.) 찾아보니 clear() 함수가 있었습니다. 영어 점수 입력을 받기 전에 cin.clear()를 호출해 주었습니다. 그러나, 기대와 달리 증상은 똑 같았습니다. 우~~씨!.... MSDN의 cin 도움말을 찾아보며 쓸만한 함수를 찾아보았지만 도움이 될만한 함수가 쉽게 눈에 띄지 않았습니다. 그사이 아내한테 전화가 왔습니다. 해결했냐구?!. 컥! ^^; 어디가 문제가 되는지 알았으니 좀더 기달려 보라고 했습니다.
MSDN의 키워드 검색기 성능이 떨어지는 관계로 결국 혼자 해결하지 못하고 구글을 통해 검색을 해보았습니다. 그리고 다음의 문서로 부터 바로 해답을 업을 수 있었습니다.
cin 객체는 입력값을 변수에 넣는 과정에서 변수의 형에 따라 변수에 입력할 값을 자동으로 취하는데, int 형임으로 99.5 중 99는 취해서 변수 kor에 넣어주고 .5는 버퍼에 남겨둔채, 자신의 상태값을 아직 버퍼에 남은게 있다는 not ok 상태로 표시합니다.
그런데, 영어 점수 입력단계로 넘어가 cin은 buffer에 남은게 있기때문에, 사용자 입력을 기다리지 않고 버퍼에 들어 있는 것을 eng에 입력하는 것을 시도하고 버퍼에 남은 값 .5가 정수가 아니기때문에 eng 값을 본래 값 그대로 둔채 다음으로 진행함으로서, 결국 이게 계속 반복됨으로서 영어 점수 입력 루틴에서 무한 루프에 빠지게 된 것이었습니다.
어떻게 알았는지 아내한테 두번째 전화가 왔고, clear()와 ignore()에 대해 말해 주었습니다. 그랬더니, 맞아 수업시간에 들었었어!. 하는게 아닙니까? ^^;
clear()가 에러 상태값을 ok 상태로 해주는 것이 맞지만, clear()만으로 되지 않았던 것은 cin은 버퍼에 무언가 남아 있으면 더이상 사용자 입력을 받지 않고 버퍼가 빌때까지 변환을 시도하기 때문에. ignore()를 호출하여 강제로 버퍼를 비어주어야 했던 것입니다.
또한 그럼 문제되는것은 영어 점수 루틴이겠네!, 하고 생각할 수 있지만 만약 국어 점수로 숫자를 입력하지 않고 문자열을 입력하게 된다면 국어 점수 입력 while문에서 무한 루프에 빠져버리게 됩니다.
그래서 저는 코드를 다음과 같이 바꾸어 아내에게 전해 주었습니다. 이미 아내는 해결했다 했지만, 내 예외 처리가 마음에 들면 이걸 쓰라구 전해 주었습니다.(^^; 뭐가 이리 복잡하냐며 싫탭니다.) [code] int kor=-1, eng =-1, math =-1; int tmp; int wrong_score=true;
저의 주관적인 의견으로는 경험적 지식이 근본 이론보다 훨씬 중요하고 유용한 경우가 실생활에서 많이 존재한다고 생각합니다. 아니 거의 모든 실무에서 경험적 지식이 이론보다 문제를 해결하는데 있어 훨씬 도움이 됩니다. 그러나 유독 IT분야에서 지식이 갖는 문제점은 그것의 유효 기간이 무척이나 짧다는 것입니다.
IT분야에서 경험적 지식을 추종하는 엔지니어가 갖게될 미래상은 습득해야 할 지식의 태산 앞에 고꾸라져버린 자신의 모습이 아닐까 합니다.
그렇다고 원리만 좇는 것도 문제가 있습니다. 이론과 원리에는 빠싹한 사람이 현장 실무에서 전혀 도움이 되지 못하고 오히려 방해자가 되는 일이 비일비재합니다. 공학에서는 오차와 오차 범위내에서의 편법을 이용한 효율 재고가 존재합니다. 하지만 이론과 원리를 너무 추구한 나머지, 그 완벽함과 기술수준은 뛰어나나, 실무에 아무런 효용도 없는 결과물이 생성되기도 합니다.
그래서, 실질적으로 제가 속한 프로그래밍의 세계에서 이론가는 환영받지 못하는 측면이 있다고 생각합니다. 즉, 프로그램밍 세계에서 OOP, UML, 컴퓨터의 구조, OS, OSI(Open Systems Interconnection) 7계층 등등 그 이론을 줄줄 나열하며, 네트워크 프로그램을 만들때는 객체지향적으로 UML을 통해 설계해야 하며, OSI 7계층이 어떻니, 어떤 계층에서 어떤식으로 처리해야만 한다는 이론을 줄줄 나열하지만, 정작 네트워크를 통해 파일을 전송하는 프로그램을 만들어오라고 하면 두손을 들어버리는 경우를 드물지 않게 보게 되기 때문입니다.
그럼 도대체 이 치열한 세상에서 새로운 기술 이론과 경험적 지식으로 무장한 후발자에게 뒤쳐지지 않을 방법은 무엇이 있을까?
그래서, 현재 제가 새운 생존 법칙은 되도록 많은 경험적 지식을 끊임없이 습득하되, 경험적 지식을 자신만의 이론을 세우는 좋은 예로 활용하여 새로운 기술 이론 습득에 활용해야 한다는 것입니다.
즉 경험적 지식을 단순한 지식 습득만으로 끝내서는 않된다는 것입니다. 위의 프로그래밍 예에서 보듯 'cin에서 사용자가 잘못된 값을 입력할 것을 대비해 매 cin 입력마다 cin.clear()와 cin.ignore() 호출을 염두해 두어야 한다.' 하는 지식은 매우 한시적으로 사용되고 기억에서 잊혀질 가능성이 높습니다.
여기서, 우리는 설계이론에 있어 자동화에 대해 잠깐 생각해 볼 필요가 있는것 같습니다. 결과물을 제공 받는 입장에서의 자동화는 해당 사용자에게 매우 편리합니다.
cin이 잘못된 입력을 받으면 잘못된 부분을 알아서(버린다) 처리하고 다음 입력을 받을 준비를 자동으로 처리해준다면 정말 편리할 것이라 생각해 볼 수 있습니다. 그러나 이런식의 자동화는 매우 위험한 결과를 초래할 수 있습니다. 이 경우는 위의 예제에 해당하는 경우에만 편리하다 할 수 있습니다. 개발자가 기대하지 않은 동작을 사용자가 함으로 인해 발생할 수 있는 심각한 문제야기에 대한 의문 자체를 갖을 수 없도록 만들어 버릴 수 있습니다.
즉, 도구를 제공 받는 입장에서 도구가 상황에 따라 무언가 자동으로 처리해버린다면 해당 사용자를 매우 난처한 상황에 직면하게할 가능성이 다분합니다. 그러므로 제가 아는한 도구를 설계하는 사람들은 해당 도구에 문제가 발생한다면, 그 문제 해결을 사용자가 할 수 있도록 남겨둡니다.
오늘 이글을 쓰게한 이유가 되었던 위 예제가 정작 이글에서 주장하는 저의 생각을 뒷받침하기에 부족한 점이 있을지 모르겠으나, 그동안 아마도 잠시 잊어버렸을지도 모르는 저의 생존 원칙을 떠오르게 하였습니다.
무언가 경험적 지식을 습득하게 되면 그 지식(cin사용시 주의할점) 또는 다른 지식들(stringstream에서도 비슷한 경우가 있다.)과 연계하여 속에 숨어있는 불변의 원리-비록 그 대상이 변하더라도-(도구를 설계하는 입장에서 도구에 이상이 발생했을때 자동으로 처리하기 보다는 사용자가 이를 인지할 수 있고, 해결할 수 있도록 하는 방법들을 제공하는 방식으로 더 많이 설계되어진다.)를 이해하고 기억할 필요가 있다. 라는 것입니다.
이런 자신만의 이론을 확립해두면, 입력받은 스트림을 Lvalue의 형에 따른 자동 형변환 및 파싱을 해주는 다른 새로운 객체를 다룰 때, 기대하지 않은 사용자의 입력에 대한 예외처리의 중요성과 당연이 이를 위한 방법을 제공할 것임으로 이런 것들을 미리 찾아보면 되겠다고 생각할 수 있게 되지 않을까요? (^^; ㅋ... 그러나, 저는 극심한 수양부족으로 도대체 이게 뭔일이다냐?! 하며 전혀 감조차 잡지 못하다가, 결국 구글신의 도움으로 알게되어 아내에게 그나마 체면치레할 수 있었습니다. ㅠ.ㅠ.)
ㅋ.... 결국 내가 부족한 것에 대한 넋두리가 되어 버린것 같군요. 언젠가 아내와 둘이서 치과 의사인 아내의 언니를 부러워하며 오갔던 말이 떠오릅니다. '자기 언니 같은 경우, 우리처럼 계속 공부할까?!', '아니, 그런것 같지 않던데?, 왜 계속 공부해야 하는지 이해를 못하는것 같더라구!', 'ㅠ.ㅠ 왜 우리는 진작 의과대학이나 법학, 약학과 같은 것에 지원할 생각을 못했을까?, 지금 생각하면 그 사람들이 참 현명하단 말야! ㅠ.ㅠ' ^^; ㅋㅋ.
Track this back : http://www.codeforum.net/blog/pitoosung/trackback/171
Tracked from Life Is Always Emergency 2008/01/19 11:45 x
제목 : 내가 생각하는 한의학의 문제점
의학은 과학입니다. 내가 연구한 결과는 다른 사람도 인정할 수 있어야 합니다. 또한 사람이 하는 학문이기 때문에 나 혼자의 경험만이 진실이라고 말할 수 없습니다. 내가 한 연구가 제대로 됐는지, 방법이 잘못된 것은 아닌지 자신할 수 없습니다. 이런 점들을 보완하기 위한 것이 바로 학술지입니다. 내가 연구한 내용을 학술지에 논문으로 제출을 하면 그 분야의 최고의 권위자들이 그 내용을 검토하고 문제 없이 가치가 있는 내용이라면 학술지에 실리기 됩니......more
저도 예전에 학교를 쉬면서 아르바이트로 코딩을 하던 일이 있어서 디버깅의 짜증남을 조금은 압니다. ^^ 하루 종일 고민하다가 해결을 못하다가 다음 날 아침에 5분만에 해결하고 왜 이걸 몰랐을까 고민하다가 그런 경험들을 모아서 따로 정리해 두기도 했죠.
의학에서도 비슷한 면이 있는 것 같습니다. 의학 전반적인 지식이야 본과 4학년을 마치고 시험 준비를 열심히 한 졸업생이 가장 쌩쌩하게 많겠지만, 실제 환자 진료는 할 수 없죠. 결국 임상 경험이 없는 의사는 환자를 볼 능력이 부족합니다. 이론서를 열심히 습득해도 실제 코딩 경험이 없으면 실무에 투입할 수 없는 것과 비슷하다고 할까요?
하지만 반대로 책 한 권 읽지 않고 무조건 경험만으로 부딪히는 것은 분명히 한계가 있습니다. 병원 생활을 오래 한 간호사들은 막 병원에 들어온 인턴 이상으로 임상 경험도 많고 실제로 인턴보다 더 옳은 판단을 많이 하지만, 이른바 루틴에서 벗어난 예외적인 상황에서는 그래도 이론적인 지식을 갖춘 인턴들이 더 나을 수 있습니다. 즉, 반복된 경험으로도 충분히 지식이 쌓일 수 있지만, 옳지 않은 지식을 습득할 수도 있고(경험으로 인한 성급한 일반화의 오류?) 경험하지 못한 것에 대해서는 대처가 전혀 안되는 거죠.
물론 피투성님처럼 그런 경험에서 일반화된 원칙들을 끌어낼 수 있는 능력이 있으면 경험을 통해 한단계 성장하는 훌륭한 의사(또는 엔지니어)가 될 수 있지만, 모든 이에게 그런 것을 기대하기는 어려운 것 같습니다. 그런 실무와 접목되고 이론과는 거리가 있을 수 있는 원칙들을 좀 더 문서화, 체계화한다면 좋은 지침이 되지 않을까요? 의학과 전산의 차이는 여기에 있는 것 같습니다. 전산은 사람이 만들어낸 산물에 대한 학문으로 그 배경의 이론도 이미 사람이 만들어 놓은 것이지만, 인체는 사람이 아직도 이해하지 못한 부분이 많으므로 학문 자체가 이론이나 원리를 모르고도 질병의 치료라는 목적만 달성한다면 우선 만족하는 부분이 있기 때문이죠. 즉, 전산으로 따지면 이론적인 배경은 모르는 체로 각종 라이브러리의 객체와 메쏘드 사용법만 죽 익히는 것과 비슷하다고 할까요? ^^
처음에는 제 블로그에 왜 트랙백이 걸렸을까 의아해했는데 끝까지 읽어 보니 재밌는 내용이네요. ^^
P.S. 의사들도 공부를 계속 합니다. 아무래도 바뀌는 부분이 많으니까요. 물론 거의 공부를 하지 않으냐 정말 많이 하느냐는 개인적인 성향이나 상황, 위치에 따라 다르겠지만요.
가끔씩 집에 있는 HDTV로 지상파 HD방송 프로그램을 보다가 당황하게 되는 경우가 있다. 뜬금없이 화면의 인물들이 하는 행동이나 상황을 자세히 설명하는 나래이터의 목소리가 흘러나오기 때문이다.
조금만 들어보면, 금방 그 용도를 짐작할 수 있다. 아, 저렇게 설명해주니 시각장애인들이 화면이 잘보이지 않아도 내용을 이해할 수 있겠구나....
^^; 그런데, 정작 문제는 잘 보이는 정상인에게는 고욕이 따른다는 것입니다. 해당 영상에 대한 몰입도가 현저히 감소하기 때문입니다.
물론 일반인에게 불편하니 없애자라거나 그런것을 주장하고자 하는것이 아닙니다.문자방송을 포함, 장애인 분들을 배려한 것이니 하루 빨리 모든 방송분에 확대되고, MPEG4 기술을 이용 문자방송도 하루빨리 전용 수신기 없이도, HD 수신기를 내장한 어떤 TV에서나 볼 수 있게되기를 희망합니다.
사람의 이기적인면 때문에, 저에게는 별 상관도 없어 보이는 화면해설방송(DVS)에 대해 글을 쓰게된것은, 저에게 불편한 상황이 발생했기 때문입니다. 집에 있는 LG HDTV에서 도저히 이 해설방송의 나래이터 목소리를 끌 방법을 찾지 못했기 때문입니다.
MBC인지 아니면 KBS인지 기억은 안나지만, 먼저 해당 방송 채널을 HD 채널과 일반 SD 채널로 전환해 가면서 비교해 보았습니다. 분명히 HD 채널에서는 나래이터의 목소리가 흘러나오고, 일반(SD)채널에서는 그 목소리가 나오지 않는것으로 보아, HD 채널의 MPEG4 스트림에서 나래이터의 목소리를 주오디오 외의 부오디오를 이용해서 보내는 것으로 추측해보았습니다.
그러나 아래의 게시물(^^; 특정 제품의 QA이지만, 다만 내용중 좋은 정보가 포함되어 있으므로 참고자료로 활용했습니다.)
네이버 지식인에서도 찾아보았지만, 위의 글 내용에서도 나오듯 TV의 음성다중 기능을 이용하면 "한국어"에서만 해설방송이 나오고, 다른 언어에서는 나오지 않는게 정상인듯 보입니다.
그런데, 저의 경우 음성다중의 언어를 무엇으로 바꾸어 보아도 ㅠ.ㅠ 해설 방송이 계속 나왔습니다. 결국, 문제는 해결하지 못했습니다.
일단 의심가는 것은 LG HDTV에서 사용하는 MPEG4 디코더 칩에 버그가 있거나, 케이블에서 지상파 HD 신호를 재전송하면서 Converting 시 문제가 있거나, 아니면 위 글에서 잠깐 언급한 아예 DVS가 주음성에 포함되어 오기 때문에 DVS만 끌수 없다(방송국에서 그랬다면 이는 SD 채널에서도 나와야 한다고 보기때문에, 신빙성은 없어보입니다.)가 될 수도 있습니다.
맘 같아서는 컴퓨터의 HDTV카드를 이용 당장 TS 스트림을 캡처하여 분석해 보고 싶으나, ㅠ.ㅠ 밀린 일이 너무도 많기에....
결국 현재는 SD채널로 돌려 해당 방송을 시청하는 것으로 해결하였지만, 화면해설방송이 확대되어, 저녁시간때의 방송분에도 편성이 된다면, 아마 저와 같은 불편을 겪는분들이 늘어난다면, 해결방법이 곧 제시되리라 봅니다. 그때도, 저만 그렇다면 결국 스트림을 분석해 보아야 겠지요.
어째든 좀 찌껍한 마음을 지울 수 없습니다. ㅋㅋ.... ============================================= 생각난 것이있어 추가합니다. 위의 Q/A글 중 두번째 답변의 스트림중 AUDIO PID오류에 의한 일시적 증상이라는 것이 신빙성을 갖는 사건이 있었던게 기억납니다. 지금 확인해보니 방송을 보았던 채널이 SBS였네요. 그 방송을 본 다음날 TV를 켜니 유독 SBS가 음성이 나오지 않는 것입니다. 얼마뒤 그 이유를 알 수 있었습니다. 가끔씩 HD채널 내에서 드라마와 광고 사이의 HD와 SD 스트림 전환중 Audio가 나오지 않는다든지, 화면에 오류가 생긴다든지 하는 경우를 보기 때문에, 그런 증상중의 하나로 보았었습니다.
그런데 아무리 채널을 다른곳으로 두었다가 다시 돌리고, 껏다 켜보아도 SBS만 음성이 나오지 않는것입니다. 우연히 음성 다중 버튼을 눌러보았더니 영어로 되어 있더군요, 돌이켜보니 DVS 테스트 하면서 영어로 둔채로 그대로 두었었나 봅니다. 다른 채널에서도 영어로 해보니, 음성이 들리지 않게 되더군요.
지금 보는 "뉴하트"를 테스트 해볼려고 했더니 ^^; 한국어 밖에 선택이 되지 않네요. ㅋㅋ DVS 방송시 한국어포함 약 4개국어 선택이 되었던 것으로 기억합니다. 그런데, 4개국어 모두 본 방송 음성과 DVS 음성 모두가 나왔던 것으로 기억합니다.
즉 그렇다면 역시 방송국의 스트림 인코딩중, 아니면 전송중 잡음이 섞여 AUDIO PID에 일시적인 오류가 있어 문제가 있었던 것으로 볼 수 있을것 같습니다.
그동안, 화면이 깨지거나, 중간에 멈춰버리거나, 난데없이 음성이 나오지 않거나 하는 것을 저는 LG HDTV의 디코더가 문제를 갖는 걸로 생각했는데, 지금 추론해보니 디지털이라고는 하지만 전송중 잡음에 의한 신호 왜곡이 생길 수 있고, 이로 인해 스트림에 변화가 생기고, 이를 해석하던 TV의 디코더가 이런 에러 스트림을 해석하게 되면서 문제를 발생하는 것으로 보입니다.
물론 MPEG4는 스트림 중간의 에러로 부터 자유로울 수 있도록, 금방 에러로 부터 정상으로 회복할 수 있도록 구성되어 있는 것으로 알고 있습니다. 즉 스트림 중간 중간에 잡음이 섞여 스트림이 깨지더라도 잠깐 오류를 보였다가 금방 해소된다는 것이지요.
아마, 에러로부터 얼마나 금방 회복될수 있는가 하는 것은 디코더 칩의 성능 문제로 보아야 할지도 모르겠습니다.
여튼 방송국 스트림 생성기의 불안, 전송중 스트림의 깨짐, 디코더의 완벽하지 못한 에러 회복기능 등등 아직 좀더 안정적인 방송을 위해 가야할 길이 많이 남아 있는지도 모르겠네요.
나중에 추가되는 중요한 서비스를 받기 위해, 현재 HDTV로는 안되어 TV를 교체하는 불상사가 생기게 되는건 아닌지, 뜬금없는 걱정을 해봅니다. ㅋㅋ
결론적으로, 이번 사건으로 디지털 TV 방송은 아직 표준이 완성되지 않은듯한 느낌을 받았습니다. 아참, 편성표를 기억해두었다 기회가 되면 담에 일시적 현상이었는지 꼭 확인해 봐야겠네요.
=================================== 다시 DVS 편송된 KBS 프로그램을 확인해보니, 역시 아마 전송중 스트림이 잡음에 의해 깨진, AUDIO PID 오류에 의한 일시적 현상으로 보입니다. 음성 다중버튼으로 한국어 선택을 하면 DVS가 나오지 않고, 영어 선택을 하면 나오네요. ^^; 괜한 걱정을 했었군요. ㅋㅋ ...
BIOS에서 표시되는 Extended Memory는 (719872K[737148928] + 640K[655360] = 737804288) 로 real memory 에서 BIOS에서 표시한 메모리를 제하면 정확히 327680(320K)가 부족한데, 이는 BIOS에서 사용하는 것이 있는 것으로 보인다.
얼추 real memory가 실제 Physical memory와 일치하는 듯 하다. 그러나 다음의 포스트를 보면 http://elenoa.tistory.com/43 8G 시스템에서는 real memory 표시가 약 9.5G정도로 실제 메모리를 훨씬 초과함을 알 수 있다. 일단 아래의 sysctl에 의한 physical memory는 좀 부정확해 보이나, real memory의 정보 역시 무한 신뢰할 수도 없는것 같다.
David Schultz wrote:
>On Sun, Oct 12, 2003, Dag-Erling Smrgrav wrote:
>
>
>>I've gotten used to the fact that there is a small discrepancy between
>>real and available memory, but I was surprised to see the following in
>>dmesg on a new P4 system:
>>
>>real memory = 1073676288 (1023 MB)
>>avail memory = 1037799424 (989 MB) #역주 : 정확히 34M 차이를 보입니다.
>>
>>That's a full 40 MB difference... where does that memory go? is it
>>used for page maps or something like that?
>>
>>
>
>Unless this is related to Peter's recent machdep.c changes, the
>difference is probably just random chunks of memory that the BIOS
>decided to use. This could include a shadow copy of the BIOS, the
>BIOS data segment, maybe a frame buffer for a cheap integrated
>video card, etc. If you do a verbose boot, you'll get a list of
>the chunks of memory that are taken according to the BIOS.
>
>
>
(번역)
이 주제는 제 흥미를 자극하는군요. 그래서 저는 이것에 관해 약간 연구를 해봤습니다.
(제 512M 머신에서는 24M의 차이를 보이는군요)
This piqued my interest, so I studied it a bit. (My 512MB machine was
showing a 24MB difference)
그 메모리(차이나는)의 대부분은 vm_mem_init()에서 호출된 두개의 함수들에 의해 소비됩니다.
Most of the memory is swallowed by two functions called from vm_mem_init():
커널은 미리 사용가능한 메모리의 모든 page를 위한 vm_page 구조체를 할당합니다.
이 구조체의 사이즈가 72bytes입니다. (vm_page.c에 있는 vm_page_startup()을 보세요)
The kernel allocates a vm_page structure for every page of available
memory early on. These are 72 bytes in size. (see vm_page_startup() in
vm_page.c)
이후로, pmap code가 각각의 vm_page를 위한 pv_entry 구조체를 할당합니다.
(저는 이것이 아마도 훨씬 후에 할당될수도 있다고 생각합니다.
그러나 일단 각 페이지가 mapped 되면 적어도 이 구조체가 많이 필요하게 될 것입니다.)
이것이 각각 28bytes입니다.(pmap.c의 pmap_init()를 보십시오)
Later, the pmap code preallocates a pv_entry structure for each vm_page
(I assume it can probably allocate more later, but will need at least
this many if each page is mapped once). These are 28 bytes each. (See
pmap_init() in pmap.c)
커널 그 자체도 또한 real memory를 사용할 것입니다. 커널은 4MB의 메모리에 로드됩니다.
그리고 그 순간에 이후 4MB의 여유분이 소비되는 것으로 나옵니다.
저는 항상 그렇다고 확신하지는 않습니다.(PSE에 안내되어진것 때문에...)
불가사의한 Pentium 버그들에 대한 Bosko의 수정본이 제출되었기 때문에 바로
그것 때문이라고도 확신할 수 없습니다.
만약 당신이 운용중인 시스템의 "phys_avail" 배열을 관찰한다면, 당신은 커널을 위한
'hole(공간)'이 얼마나 많이 (메모리)를 차지하는지 볼 수 있습니다.
The kernel itself will come out of real memory too. The kernel is loaded
into 4MB pages, and any residue in the last 4MB page appears to be lost
at the moment. I'm not sure if this was always the case (well, since
PSE was introduced) or if it's just an issue since Bosko's fix for the
weird Pentium bugs was committed. If you look at the "phys_avail" array
of a running system, you can see how much the "hole" for the kernel
takes up:
> petere at hippo# gdb -k /usr/src/sys/i386/compile/HIPPO/kernel.debug
/dev/mem
> GNU gdb 5.2.1 (FreeBSD)
> [snip]
> (kgdb) p phys_avail
> $1 = {4096, 651264, 1048576, 4194304, 12738560, 526987264, 0, 0, 0, 0}
> (kgdb)
이 배열은 부트때 발견된 물리적인 메모리의 범위를 보여줍니다. (0번째 부터 샌다고할때)
짝수 번째것은 범위의 시작위치, 홀수 번째는 끝이됩니다.
제 시스템의 경우 4194304와 12738559사이의 공간이 보입니다 :
여기에 커널이 로드되어 있습니다.
당신의 phys_avail map에 약 8MB의 Kenel을 위한 공간이 있다고 가정하고,
"avail memory" 메시지가 출력되기 전에 소모된 공간의 최소 추정치는
다음과 같이 계산될수 있습니다. :
This array shows the spans of physical memory that were found at boot
time. The even elements (counting from 0) are the start of the span,
with odd elements being the end. My box shows a hole between 4194304 and
12738559: This is where the kernel was loaded. Assuming your phys_avail
map had a similar 8MB hole for the kernel, then the minimum estimate of
the amount of space consumed before printing the "avail memory" message
can be calculated as follows:
Available memory in pages = 107366288 / 4096 = 253369
Space Lost to struct "vm_page"s: 253369 * 72 = 18242568
Space Lost to struct "pv_entry"s: 253369 * 28 = 7094332
Space Lost to kernel "hole": 12738560 - 4194304 = 8544256
--------
33881156 (역주 : 약 32.3MB)
그것은 당신이 본것에서 2M 차이 안쪽에 있습니다.
당신은 아마도 먼저 로드된 kld admin과 메시지 버퍼를 위해 약간의 공간을
더 소비할 수도 있습니다. ~???
that's within 2MB of what you're seeing. You can probably take out some
more space for preloaded kld admin overhead, and the message buffer, and
probably plenty more I can't think of (BIOS and WITNESS SYSINITS at
least happen between the final print out and the VM initialisation: that
probably accounts for a lot of the remainder)
요약하면 커널 이미지 자체의 메모리 적제로 소비하는 것과 커널에서 메모리 관리를 위해 할당한 구조체가 차지하는 메모리, 그리고 기타 소비된 메모리에 의해 차이가 난다는 것
위에 언급한 계산법을 적용해보면(커널 hole을 10M로 봤을때29M에서 약 2M의 오차 범위내 들어갑니다.)
본 시스템의 결과를 위에 언급된 계산법으로 적용해본것 738131968/4096=180208
정확히 계산은 않해봤지만, 딱 보기에 명확한 리눅스에 비하면 어째든 조금은 애매함. Memory: 1291944k/1310656k available (2080k kernel code, 17452k reserved, 869k data, 220k init, 393152k highmem)
FreeBSD가 워낙 눈에띄게 저부분을 출력하는 지라, 참 이상하다 하고 분석해 보았는데, 사실 리눅스와 크게 다를것은 없어 보입니다. 다만 리눅스와 비교했을때 소비된 메모리 정보를 표시하지 않아, 사용자로 하여금 궁금증을 유발하는 것으로 보입니다. 또한 위 정보대로라면 메모리 관리를 위해 너무 많은 메모리를 사용하는 것으로 보입니다.
Track this back : http://www.codeforum.net/blog/pitoosung/trackback/169
Tracked from 엘레노아의 작업로그 2008/01/18 14:41 x
제목 : FreeBSD 6.2, 64bit, 메모리 8G 머신의 dmesg에서 real memory가 너무 높게 나오는 현상
아래는 물리적인 메모리 8G 가 꽂혀 있는 서버의 dmesg 내용중 일부이다. ... real memory = 10200547328 (9728 MB) avail memory = 8261935104 (7879 MB) ... 어라라? 물리적인 메모리는 8G인데, real memory 항목이 9728 MB가 찍혀 있다. 뭐 언뜻 보더라도 8G는 훨씬 넘어 보인다. 여러 웹서핑 결과, PC의 정확한 물리적인 메모리를 검색하는 방법은 아래와 같다. eleno.....more