|
컴퓨터 CPU 단위에서는 짧은 시간에 아주 엄청난 규모의 일들이 일어난다. 2.5Ghz CPU라면 1초에 클럭이 25억번 온다는 소리고 아주 이상적인 경우, 최신 CPU들은 1초에 25억개에 근접한, 아니면 그 이상의 명령어들을 처리할 수 있다. 그래서 고작 42억개까지만 기억할 수 있는 32비트 정수로는 CPU 내부의 통계치를 담기에는 너무 부족하다. 그래서 대부분 주요 CPU 내부 상태, 예를 들어 클럭 발생 횟수나 지금까지 수행한 명령어 개수는 64비트로 표현을 해야한다. 64비트는 대략:
1천 8백 경에 해당하는 숫자이다. 총 19자리 숫자. 우주의 나이 대략 100억년 광년을 킬로미터 단위 (대략 9.4조 Km/LY)로 바꾸면 10^22가 나오니 이런 엄청난 숫자에 대략 버금간다. 프로파일링 툴을 하나 만들고 있다. 이 툴은 프로그램이 수행한 명령어 개수 따위를 헤아린다. 이렇게 컴퓨터 내부에서 일어나는 숫자의 단위가 엄청남을 잘 알지만 결과에 나오는 수천억이 훌쩍 넘는 명령어가 처리 되었다는 결과를 보면 아찔하긴 하다. 첨엔 “왜 이렇게 많어?” 라고 의심을 하고 내가 프로파일 툴을 잘못 짰나 의심이 갈 정도다. 그것도 고작 몇 분 돌아가는 프로그램이 저런 수천억, 경단위의 명령어들을 처리한다.
그런데 이런 통계 출력 과정 중에 대단한 삽질을 하나 하였는데, 지난 번에 한 번 printf와 cout이 만들어주는 구문을 비교하며 cout의 비효율성(?)을 지적한 바 있다. 그러나 수행성능을 고려치 않으면 확실히 cout이 더욱 편할 때가 있는데 32비트 및 64비트 정수형이 혼재되어있거나 플랫폼 독립적으로 만들고 싶을 때는 삽질을 꽤나 줄일 수 있다. 플랫폼에 상관없이, 타입 신경쓰지 않고 그냥 << 만 주면 되니 편리하다.
바보처럼 실수로 64비트 정수를 그냥 32비트 정수 찍듯이 %u를 주고 말았다. 그런데 이 사태로 벌어지는 일은.. 1915930505, 18396, 2681561585995870000000000000... (생략) 대략 멍하다. 이런 망가진 결과를 보고 난 한참이나 어디 자료구조가 꼬이거나 메모리 버그가 났나보다 한참을 들여다 봤다. 그러나 순전히 printf에서 실수를 한 결과. %u는 4바이트만 읽는데 인자로는 8바이트를 줬고 이것이 밀려서 괴상하게 찍힌 것이다. 위 예와 같이 특히 실수형이 있으면 숫자가 아름답게 나오기 때매 메모리 관련 버그로 의심하기 십상이다. 이럴 땐 VC++ (msvcrt) 에선 %I64d, GNU libc에서는 %lld와 같이 줘야한다. Unsigned일 때는 d 대신에 u가 되어야 한다. x86-64 환경이라해도 int는 4바이트이므로 알아서 잘 찍어주겠지라고 생각하단 역시 삽질한다. 플랫폼마다, 비트 크기에 따라, signed/unsigned에 따라 %?를 맞추는 것이 여간 삽질이 아니다. 이런 점에선 확실히 C++ stream을 이용하는 것이 좋다. 또 여기에 유니코드 문자열을 출력할 때 %s냐 %S냐의 삽질도 만만치 않다.
최근 등록된 덧글
개발자 입장에서의 수많은 ..
by Jiyoon at 02/04 저도 아들 돌잔치때 돌잡이 .. by 박상욱 at 01/18 미국 대학원 원서 작성중에 p.. by 태클사이야 at 01/13 TO: 박PD 로그인 하지 않아.. by 박응용 at 01/10 http://gigglehd.com/zbx.. by dhunter at 12/28 우와.. 좋네요. 태반이 .. by 윤광배 at 12/17 항상 좋은 글 잘 보고 있습니.. by y2k at 11/23 글이 좋아서 제 블로그에 담.. by 쏭섭 at 11/23 최근 등록된 트랙백
메뉴릿
이글루 파인더
|