1. 자동차

1930년대에 일본군 장성인 야마모토 이소로쿠가 미국으로 여행인지 출장인지를 갔는데..
시골 깡촌의 평범한 소녀가 공구를 들고 와서 자동차가 퍼진 걸 뚝딱 수리하는 걸 목격했다.
그는 이거 하나만으로도 천조국의 저력을 직감하고 경악했으며, 일본은 이런 나라와 전쟁을 벌여서는 이길 수 없다고 확신하게 됐다고 한다.

참고로, 옛날에 성경 번역자 틴데일은.. 시골에서 소 모는 꼬맹이 조무래기라도 교황보다 성경을 더 많이 알고 자국어로 성경을 암송할 수 있는 세상을 만들겠다고 포부를 밝혔었다. 근데 이 미친 나라는 어떻게 듣보잡 시골 처자조차 기계를 이렇게 잘 다루느냐 말이다.

2. 컴퓨터

한편, 1940년대인가 50년대인가, 컴퓨터 과학자 폰 노이만은 거의 인간 컴퓨터 급의 큰 수 암산이 가능했으며, 그냥 머릿속으로 기계어 코드를 쭈룩 읽고 쓰는 게 가능했던 천재 괴수로 유명했다.
자기 제자들이 컴파일러는커녕 어셈블러를 만드는 것조차 별로 달갑지 않게 봤을 정도였다. 프로그램을 짜고 싶으면 사람이 그냥 직통으로 0 1 쑤제 암산 기계어 코딩을 하면 되지, 엔지니어가 지 한 몸 편하자고(!!) 그 비싸고 거대하고 귀한 컴퓨터를 갖고 무슨 자원 낭비 잉여짓을 하느냐고, 그렇게 힐난을 가했었다.

하긴, 폰 노이만은 컴퓨터에 대해서 '프로그램 내장형 모델'이라는 개념 자체를 최초로 만든 사람이었다..!!!
컴퓨터가 해야 할 일을 일일이 진공관 배선을 바꾸고 천공 카드를 교체하는 식의 물리적인 노동으로 지정하는 게 아니라, 이 지시사항 역시 프로그램이 취급하는 데이터와 동급으로 메모리 상의 정보 중 하나로 간주시키는 발상이다.

요즘처럼 키보드 코딩만으로 간편하게 컴퓨터 프로그래밍이 가능해진 것 자체가 이런 개념이 도입된 덕분이다.
그러니, 자기가 이 정도로 프로그래밍 환경을 개선했으니, 더 편한 요행 꼼수를 바라지는 마라~~ 그런 생각을 했던 건지도 모르겠다.

3. 저격총

역시 2차 세계 대전 때.. '시모 해위해'라고 적군 수백 명을 사살한 핀란드의 전설적인 저격수가 있었다.
그는 저격 잘 하는 비결이랍시고 번거로운 조준경 따윈 없는 게 낫다는 말을 씨부려서 다른 사람들을 경악시켰다(!!). 지 혼자 시력이 2.0 3.0을 넘기라도 하는지.. 아무도 이해하지도 이행할 수도 없는 비현실적인 조언을 조언이랍시고 진지하게 남겼던 것이다.

하긴, 그 시절엔 레이더도 없거나 뒤늦게 개발됐었다. 그렇기 때문에 전투기 폭격기 조종사 역시 시력이 좋은 게 지금보다 아득히 유리하게 작용하긴 했었다.

이것들은 대단한 일화인 것이 사실이다. 하지만 저 시대 사람들이 오늘날과 같은 급의 자동차를 수리하거나 요즘 컴퓨터와 운영체제 같은 여건에서 기계어 코딩을 한 건 아니라는 점 역시 감안할 필요가 있다.
당연히 지금 자동차나 컴퓨터는 정말 저 때와는 비교조차 할 수 없을 정도로 훨씬 더 복잡하고 정교하다. 그렇기 때문에 사람이 호락호락 직접 만지고 고칠 수 있지 않다.

제 아무리 천재 괴수 폰 노이만이라 해도, 그 시절에 컴퓨터라는 건 핵 실험이나 탄도 계산, 일기예보 시뮬레이션을 위한 거대한 계산 기기 그 이상도 이하도 아니었다. 국가 기관· 연구소만의 전유물이었으며, 국민의 세금으로 운용되는 엄청 비싸고 귀하신 몸이었다.

그는 2차 세계 대전을 겪었고, 미국의 원자폭탄 개발에 참여했을 뿐이었다. 일반 양민들이 개나 소나 그 거대한 컴퓨터보다 성능이 더 뛰어난 스마트폰을 주머니에 넣고 다니는 시대를 살았거나 그걸 예측한 건 아니었다. 그러니 컴퓨터 자원에 대해서 극도로 아껴 쓰고 절약하자는 마음이 뼛속까지 몸에 배겼으며, 그런 사고방식이 자신의 천재적인 두뇌와 결합했기 때문에 '쓸데없이 어셈블러 따위'라는 갈굼이 나온 것이었다. =_=;;;

지금이야 한낱 작업자의 편의 때문이 아니라 업무 생산성 때문에라도 프로그래머들에게 고급 툴과 컴파일러는 듬뿍 쥐어 줘야 한다. 폰 노이만이라도 Windows용 exe 실행 파일을 맨땅에서 만들지는 못할 것이며, 근본적으로 그래야 할 필요가 없다.
키가 3m인 인간흉기 골리앗, 특수부대 할아버지라 해도 현대의 전장에서 총 맞으면 죽는 건 똑같기 때문이다.

시모 해위해도 기술이 훨씬 더 향상된 오늘날의 저격 소총을 보면 조준경 불필요 소신을 바꾸게 됐을지도 모르겠다.
이 사람은 전장에서 수백 명의 적군을 조준경 없이 저격 사살하긴 했지만, 그 대신 저격 거리도 km급이 아니고 우리 생각보다 짧았다고 한다(2~300m). 그만큼 더 위험하게 임무를 수행했다.

4. 비행기

20세기 중반의 천조국 기준으로.. 컴퓨터 업계에 폰 노이만이 있다면, 항공 업계에는 '켈리 존슨'(1910-1990)이라는 정말 전설적인 괴수 엔지니어가 있었다.
이 사람은 평생을 비행기를 조종하는 일이 아니라 비행기를 설계하고 만드는 일에 뼈를 묻었다. 이 사람도 조종을 안 한 건 아니지만, 평범한 여객이나 군용 조종이 아니라 새로 만들어진 기체의 안정성을 극한까지 시험하는 '테스트 파일럿' 명목이었다. ㄲㄲㄲㄲㄲ 즉, 여느 파일럿과는 급이 다르다.

사용자 삽입 이미지

이 사람은 록히드에서 일하다가 미국의 최신 항공 우주 기술의 산실인 스컹크 웍스의 수장을 역임했고.. 네바다 주에 그 비밀 실험 기지인 AREA 51을 직접 구상하고 만들기도 했다.;;
전투기 P-38, 최초의 제트 전투기 F-80 슈팅스타 쌕쌕이, 마하 2를 최초로 돌파한 F-104, 고공 정찰기 U-2와 SR-71 등..

컴퓨터도, 캐드도 없던 시절부터 이 사람은 인간 컴퓨터나 인간 백과사전이 아니라, 그냥 걸어다니는 풍동 실험실이었다.
"비행기를 이렇게 만들고 날개의 모양과 크기와 각도를 이렇게 만들어서 저렇게 조종하면 실제로 이렇게 날아갈 것이다, 성능과 안정성이 이럴 것이다.. 이 디자인은 요런 비효율과 문제가 있으니 얼추 이 정도로 고쳐야겠다.."

동료 엔지니어들은 낑낑대며 복잡한 수학 계산을 통해 예측을 했지만, 저 사람은 머릿속에서 직감적으로 바로 시뮬레이션이 됐다. 구체적인 숫자까지 제시한 게 굉장히 정확하게 적중했다. 이게 진짜 무서운 면모였다.;;; 동료 엔지니어들은 "저 괴수는 공기의 움직임이 눈에 보이기라도 하나?" 하며 혀를 찼다. 이 정도면 비행기의 폰 노이만 급이 아닐지? ㄷㄷㄷ

참고로 비슷한 시기에 보잉 사에서 재직했던 '조(조셉) 서터'(1921-2016)도 전설적인 비행기 개발자였다. 보잉 7x7 프로젝트에 모두 관여하면서 짬을 쌓다가 궁극적으로는 747의 팀 리더가 되어 20세기 최대 크기의 전설적인 여객기를 설계하고 개발하게 됐기 때문이다.

사용자 삽입 이미지

글쎄, 현대의 CPU 설계 중에서는 독보적이고 전설적인 장인 엔지니어가 없나 모르겠다.
CPU는 자동차나 비행기와 달리 애초부터 사람 손으로 만드는 게 가능하지 않은 물건이긴 하다만.. 그래도 미시세계에서도 회로를 이렇게 설계하면 발열이나 전력 소모가 너무 심해진다느니, 몇 마이크로초 단위의 손실이 생긴다느니 뭐니 이런 직관이 발휘될 여지가 있는지 궁금하다.

Posted by 사무엘

2023/03/08 08:35 2023/03/08 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2134

C 언어의 애환

1. 비트필드

C언어의 구조체에는 다른 언어에서는 거의 찾을 수 없는 비트필드라는 물건이 있다.
얘는 굉장히 편리하고 강력한 프로그래밍 요소이다. 바이트 경계에 딱 떨어지지 않는 숫자를 일반 숫자 다루듯이 읽고 쓰게 해 주니 이 얼마나 대단한가? IEEE754 부동소수점이라든가, 과거 2바이트 조합형 한글 같은 건 비트필드 구조체를 잘 만들어서 내부 구조를 쉽게 분석해 볼 수 있다.

다만, 비트필드와 관련해서 언어 문법 차원에서 다음과 같은 점이 보완되거나 강화됐으면 좋겠다는 생각이 개인적으로 오래 전부터 들었다.

(1) 지정 가능한 자료형은 그냥 unsigned 아니면 signed 둘 중 하나로 굳혀 버리고, 나머지 쓰잘데기없는 키워드들은 몽땅 거부하고 에러 처리했으면 좋겠다. 어차피 이 필드의 크기는 뒤의 비트수에 의해서 결정될 텐데.. int니 char이니 long이니 하는 건 전혀 불필요하고 쓸데없는 정보이기 때문이다. 괜히 unsigned char _field: 10; 이런 거 체크해서 10이 8보다 더 클 때만 에러 처리하는 건 잉여스러운 짓이다.

사실 본인은 비트필드에서 부호 "있는" 자료형이 쓰이기는 하는지, signed조차도 필요는 한지 그것도 굉장히 회의적이다. 차라리 enum이 쓰일 가능성은 있을지 모르겠다.

(2) 비트필드에서 공간을 배치하는 순서는 결국 타겟 플랫폼의 비트 endianness의 영향을 받는다. unsigned member : 4 라고 해 주면.. little endian에서는 하위 0~3비트가 할당되며, big endian에서는 상위 4~7비트가 할당된다.
더구나 비트필드라는 건 결국 2~4바이트짜리 커다란 정수 하나를 잘게 쪼개기 위해 존재하는 물건인데, 쪼개는 순서 자체가 비트 endianness에 따라 달라진다.

결국 비트필드를 사용해서 특정 파일 포맷이나 패킷 구조를 기술해 놓은 구조체 선언을 보면.. 빌드 환경의 endianness에 따라 조건부 컴파일을 시켜서 little일 때는 같은 멤버를 abcd 순으로 배치하고, big일 때는 이를 dcba 순으로 무식하게 배열해 놓곤 한다.

이게 정형화된 패턴이니 프로그래머가 쓸데없는 삽질을 할 필요 없이, 언어 차원에서 문법을 지원을 좀 했으면 좋겠다.
"이 비트필드들은 16/32비트 기준으로 큰/작은 자리부터 순서대로 분해하는 것이다. 그러니 타겟 아키텍처의 endianness가 이와 정반대이면 컴파일러가 알아서 멤버들의 배치 순서를 뒤집어라" 이렇게 힌트를 준다.

이런 일이 컴파일러가 하기에는 너무 지저분하다면 #pragma 같은 걸로 빼내서 전처리기 계층에다 담당시켜도 된다.
핵심 요지는.. 똑같은 멤버를 프로그래머가 순서만 바꿔서 다시 써 주고 조건부 컴파일을 시키는 무식한 짓만은 좀 없어져야 한다는 것이다.

비트필드가 쓰일 정도의 상황이면.. 아마 이 공간 전체를 거대한 숫자 한 덩어리로 같이 취급하게도 해 주는 union, 그리고 구조체 멤버 배치를 어느 플랫폼에서나 비트 단위로 일치하게 강제 동기화시키는 #pragma pack도 같이 쓰이고 있을 가능성이 매우 높다.
#pragma pack과 #pragma once는 진짜로 사실상의 표준이니 C/C++에서 정식 표준으로 좀 등재시켜야 하지 싶다. char32_t / char16_t 같은 게 결국 built-in type으로 받아들여지고 정식 표준이 된 것처럼 말이다.

참, 당연한 얘기이다만.. 구조체 템플릿에서는 비트필드의 크기를 나타내는 숫자도 템플릿 인자로 공급해 줄 수 있다.
비트필드의 크기는 구조체 멤버에 들어있는 배열의 크기와 위상이 거의 같으니 말이다. 구조체의 크기에 영향을 주는 숫자이며 컴파일 시점에서 값이 상수로 결정되어야 한다.

template<size_t N> struct XXXX {
    unsigned _member: N;
};

아주 C스러운 요소와 C++스러운 요소가 한데 만난 것 같다. ㄲㄲㄲㄲㄲ 비트필드의 크기를 템플릿 인자로 지정할 일은 극히 드물 것이다.;;

교통 분야에서 좌측· 우측 통행이 국가별로 찢어져 있다면, 디지털 컴퓨터에서는 비트의 배치 순서 endianness가 통행 방향과 비슷한 개념이며 아키텍처별로 찢어져 있는 듯하다.
네트워크 표준은 big endian이지만, 컴퓨터들은 x86이 주류이다 보니 little endian이 주류이다. 이건 세계적으로 자동차 도로 우측 vs 좌측과 비슷한 비율이며, 안드로이드 vs iOS와 비슷한 비율인 것 같다. 본인은 big endian을 native로 사용하는 컴퓨터를 평생 한 번도 구경해 본 적이 없다.

2. C의 단순 평면성

C++에 비해, C는 마소에서 거의 아오안 취급을 하기 때문에 컴파일러의 버전이 바뀌어도 달라지는 게 거의 없다. 다만..

  • C99에서 추가된 가변 길이 배열이 Visual C++에서는 지원되지 않는다.
  • 구조체의 가장 마지막 멤버를 구조체 자체의 크기를 차지하지 않는 명목상의 멤버로.. char data[] 내지 data[0] 같은 형태로 선언해서 구조체의 뒷부분을 가변 길이로 활용하는 게.. 여전히 일부 컴파일러의 편법일 뿐, 정식 표준이 아닌 것 같다.
  • 대소문자를 무시하고 문자열을 비교하는 함수가 의외로 표준이 아닌 것 같다. stricmp와 strcasecmp 부류가 혼재해 있다. C는 라이브러리 함수가 ANSI니 POSIX니 하면서 의외로 파편화된 게 좀 있어서 플랫폼 간의 이식성을 저해하는 중이다.

C는 클래스와 상속 계층이 없을 뿐만 아니라, 각종 명칭에 다단계 계층 scope이란 것도 없다. namespace나 using 같은 걸 신경쓸 필요 없이 모든 명칭이 오로지 local 아니면 global.. 그도 아니면 매크로 함수밖에 선택의 여지가 없다. 클래스라기보다는 번역 단위 자체가 클래스와 비슷하며 static이 외부로 노출되지 않는 private 역할을 얼추 담당한다.

그러니 뭔가 아주 단순하며, 입체적인 게 아니라 '평면적이고' 깔끔해 보이기는 하는데.. 한편으로 너무 중구난방이고 명칭이 충돌하기 쉽다.
새로 짓는 이름은 접두사에 목숨을 걸어야 할 것 같다. 이런 언어로 초대형 라이브러리를 만들고 대형 프로그램을 관리하는 데는 한계가 있을 수밖에 없다.

또한 매크로 함수를 너무 사악하게 남발 남용할 경우, 어지간히 복잡하게 꼬인 C++ 템플릿 이상으로 코드가 알아보기 어려워진다. 특히 전처리기의 존재를 알지 못하는 디버거는 매크로 함수와 완전히 상극이다.

매크로 함수 내부의 코드를 한 단계씩 실행할 수 없고, 또 ## 연산자에 의해 새로 생긴 토큰 명칭들은 어지간한 IDE에서 자동으로 파악도 못 해 준다. 이렇게 IDE와의 괴리가 커지고 붕 떠 버린 코드는 사람 입장에서도 짜증이 나서 제대로 들여다보고 유지 보수하기가 싫어진다. 이는 결국 생산성의 저하로 이어진다.
이런 게 C의 어쩔 수 없는 한계인 것 같다. -_-

3. C언어의 강력하고 자유로운 면모

  • 지역 변수, 전역 변수, heap 등 어디든지 가리킬 수 있는 포인터
  • 한 함수 안에서 어디로든 분기할 수 있는 goto문
  • type이고 뭐고 다 씹어먹고서 메모리를 조작할 수 있는 memcpy, memmove (malloc, free 같은 생짜 수동 메모리 관리는 덤)
  • 무슨 토큰이건 다 치환할 수 있는 전처리기 매크로

하지만 위의 요소들은 위험성과 복잡도도 너무 키운다. 저런 저수준 조작이 잔뜩 쓰인 복잡한 코드에서 버그를 찾아내야 된다면.. 정말 머리에서 연기가 피어오를 것이다.
오늘날의 프로그래밍 언어에서는 저것들은 최대한 금기시되고 봉인되고, 다른 형태로 대체되고 있다.

goto는 아무리 사악하다고 하지만 이중 for 문을 한꺼번에 빠져나가기, 그리고 switch와 while/for문을 한꺼번에 빠져나가기 같은 건 너무 아쉽다. 자기보다 뒤로만 goto가 가능하게 제한하는 것도 나쁘지 않을 것 같은데 말이다.
한편, 개발툴에서 define 전개된 결과 기준으로 문자열을 find in files 하는 기능이 있으면 좋겠다는 생각이 가끔 든다.

4. 전처리기 #if 의 동작 방식

C/C++에서 원래 있는 if문 말고, 전처리기의 #if에서는 소스 코드에 있는 변수들을 당연히 전혀 사용할 수 없다. 오로지 #define 심벌과 상수, 기성 연산자만이 사용 가능하며, #define 심벌들은 매크로 치환 후에 다들 상수로 바뀌어야만 한다.

변수나 type이라는 개념이 없기 때문에 대입 관련 연산자는 당연히 전혀 사용할 수 없으며 포인터도 아웃이요, sizeof 연산자도 지원되지 않는다. 그 대신, 어떤 심벌이 #define돼 있는지의 여부를 판별하는 defined라는 고유한 bool값 연산자가 있다.

sizeof는 피연산자가 값이 아닌 타입 명칭일 때는 피연산자를 ( )로 싸지 않아도 된다.
이와 비슷하게, defined도 피연산자가 다른 수식이 아니라 명칭 달랑 하나이기 때문에 ( )가 없어도 된다.

그리고 나도 지난 25년 가까이 전혀 몰랐던 특성이 하나 있는데..
#if 문에서는 정의되지 않은 아무 명칭/심벌을 들이대도 에러 처리되지 않는다. 그런 듣보잡 심벌은 그냥 곱게 상수 0과 동급으로 간주된다~!

무슨 포인터 역참조 할 때 if(ptr && *ptr==1) 이러듯이 #if defined SYMBOL && SYMBOL==1 같은 defined 가드를 설치할 필요가 없다.
SYMBOL 자체가 #define돼 있지 않다면 #if SYMBOL==1은 어차피 자동으로 false로 처리된다.
겨우 이런 사소한 사항 때문에 전처리기가 까탈스럽게 에러를 뱉지는 않으니 걱정하지 않아도 된다.

5. 특수한 코딩 요소

(1) 빌드 configuration이 맞지 않는다면 코드가 아예 빌드되지 않고 고의로 에러가 유발되게 하고 싶을 때가 있다. 이때는 일부러 무식하게 C/C++ 문법에 어긋난 문자열을 늘어놓을 필요가 없이 #error라는 전처리기 지시문을 쓰면 된다.
컴파일러에 따라서는 에러가 아니라 경고 메시지만 흉내 내고 빌드는 계속 진행되게 하는 #pagma message도 표준에 준하는 기능으로 쓰인다. deprecated API를 사용을 권장하지 않는다고 표시하는 것처럼.. 이런 건 언어 차원의 지원이 필요해 보인다.

(2) 파싱과 문법 체크만 할 뿐, 실제 코드를 생성하지 않고 아무 일도 하지 않는 허깨비 유령 함수라는 것도 필요하다. 디버그 로그를 찍는 함수를 조건부로 숨길 때, 템플릿 클래스에 인자가 제대로 주어졌는지 체크할 때 등(static_if 나 컴파일 타임 assert와 비슷)..
이건 _noop라는 컴파일러 인트린식 형태로 제공되는 편이다. 마치 인라인이나 매크로 함수처럼.. 외형은 함수이지만 실제로는 자기 주소가 존재하고 매개변수의 push/pop이 행해지는 함수가 아닌 셈이다.

(3) 내용을 깡그리 무시하고 컴파일러가 파싱하지 않게 하는 영역은 '주석'이라고 불리며, 이건 모든 프로그래밍 언어에 존재한다.
C/C++에서는 /* */ 와 //뿐만 아니라 전처리기를 이용한 #if 0 / #endif도 사실상 주석처럼 쓰일 수 있다.
게다가 얘는 /* */ 와 달리, 중첩이 가능하다. #if 0으로 막혀 있는 구간이라도 전처리기의 #if #else 로직은 무시되지 않기 때문이다. 그래서 중간에 또 #if 0이 섞여 있는 코드라도 한번에 싹 막았다가 해제할 수 있어서 편리하다.

Posted by 사무엘

2023/01/17 08:35 2023/01/17 08:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2114

1. 옛날 자동차와 컴퓨터의 성능 수동 조절 버튼

요즘으로서는 실감이 안 가지만 30여 년 전 엄청 옛날 1990년대에 286이나 386급 컴퓨터에는 자신의 클럭 속도를 저/고로 조절하는 버튼이 본체에 있었다. 일명 '터보' 버튼..
그래서 컴퓨터 본체에 달린 버튼이 전원, 리셋, 터보.. 요렇게 3개였다.

사용자 삽입 이미지

(아 맞다, 그러고 보니 옛날 컴터는 본체에 저렇게 현재의 클럭 속도가 숫자로 표시되어 나오기도 했고,
하드디스크 동작 램프도 저렇게 있었다.. 완전 까먹고 있었다!! ㄲㄲㄲㄲㄲ 하드 동작 램프는 SSD 시대가 되면서 완전히 구시대 유물로 전락한 듯하다.)

단, 터보에 대해서 오해하지 말아야 할 것이 있는데..
터보를 켰을 때 컴터가 무슨 애프터버너.. 아니, 오버클럭 모드로 진입해서 평소보다 더 빠르게 동작하는 게 아니었다. 정반대..
터보를 끄면 리미터가 걸려서 제 성능보다 느리게 돌아가고, 터보를 켰을 때 원래 속도대로 동작했다.

그리고 이런 저속 모드가 존재했던 이유는 무슨 발열이나 전력 소모 같은 이유 때문이 "아니었다". 느린 컴터를 기준으로 돌아가는 기존 프로그램과의 '호환성'을 제공하기 위해서였다.

일례로, 프레임 수 조절을 정교하게 안 하는 일부 옛날 게임은 클럭이 빠른 컴퓨터에서는 너무 빠르게 돌아갈 수 있었다. 매번 현재 시각을 측정하면서 컴터 클럭과 무관하게 프레임 수 조절을 정교하게 하는 것도 "1클럭이 아까운 CPU 자원을 소모하는 번거로운 '일' "이었기 때문이다. 그래서 그런 작업을 생략했던 것이다.;;

겨우 이런 호환성 유지를 위해 꼴랑 16MHz짜리 286 컴퓨터를 도로 8이나 12MHz 클럭으로 동작하게 하고, 56MHz짜리 386 컴퓨터를 33MHz로 너프 시켰다니.. 옛날은 참 암울하던 시절이었다.

그에 비해 요즘은 노트북 컴퓨터가 배터리만으로 동작할 때 화면 밝기와 CPU 속도를 살짝 낮추는 옵션이 있는 정도이다. 절전을 위해서..
요즘 자동차가 연비를 굉장히 신경 써서 만들어지는 것만큼이나 요즘 컴퓨터는 고성능에다 전력 소모와 발열을 굉장히 신경 써서 만들어진다.

하긴, 486은 아키텍처야 386과 동일하지만 그래도 캐시 메모리라는 게 처음으로 도입되고 부동소수점 코프로세서가(80387) 옵션 액세서리가 아니라 완전히 포함돼 들어갔고, 저런 터보 나부랭이도 완전히 없어졌다. 아마 냉각팬도 이때쯤 들어갔나?
생각해 보니 단순히 클럭만 빨라진 게 아니었고 386 대비 바뀐 게 생각보다 많았다.

이렇듯.. 옛날 컴퓨터에 터보 버튼이 있었다면, 동시기의 자동 변속기 초창기 차량에는 파워/이코노미, 오버드라이브 따위의 버튼들이 있었다.
이때는 자동 변속기가 꼴랑 4단까지밖에 지원되지 않았고, 변속 알고리즘이 지금만치 똑똑하고 효율적이지 못했다. 킥다운이나 락업 클러치, 스포츠 모드 같은 기능의 구현도 미숙했다.

그래서 이때는 파워 버튼을 눌러서 차가 평소보다 높은 rpm까지 저단을 더 오래 유지하다가 고단으로 넘어가라고 동작 방식을 강제로 바꿀 수 있었다. 당연히.. 앞차를 추월할 때, 노란불 켜진 교차로를 필사적으로 통과해야 할 때 등, 수동 몰듯이 저단에서 일부러 확 밟아야 할 때 쓰는 용도였다.
옛날 자동차, 옛날 컴퓨터에만 있었던 추억의 '모드 전환' 버튼이 문득 떠올라서 회상을 늘어놓아 보았다.

2. 쌍팔년도 PC의 그래픽 카드

- IBM에서는 CGA (320*200 4색), EGA (640*350 16색), VGA (640*480 16색, 320*200 256색)의 순으로 표준 그래픽 카드를 내놓았다.
그러나 한글· 한자 때문에 글자 높이가 최하 16픽셀급이 돼야 하는 한중일에서는 모노크롬 허큘리스 다음으로 곧장 컬러 VGA로 갈아탔다. 허큘리스는 3rd파티 싸제 규격이었다.

- 하긴, 8비트 컴퓨터는 비디오 쪽 성능이 많이 딸려서 저런 고해상도 그래픽을 표현하기가 난감했다. 우리나라에서 국가 차원에서 컴퓨터들을 교통정리를 할 때 8비트를 일찌감치 배제하고 최하 16비트부터 선택한 이유도 이 때문이었다.
16비트가 지금까지 사용되는 PC의 외형 근간을 완성했다면, 32비트는 넉넉한 주소 공간과 보호 모드 지원 덕분에 멀티태스킹/멀티스레딩/가상 메모리를 최초로 구현 가능하게 했다. 64비트는 32비트 구조에서 4G 한계만 극복한 것이고..

- CGA EGA VGA 하면 개인적으로 늘 같이 떠오르는 게.. 레코드의 규격 SP EP LP이다..;;;

- 각 그래픽 카드별로 뭔가 비공식 변조 모드가 있었다.
CGA는 해상도를 무려 160*100이라는 극악으로 떨어뜨린 16색 그래픽 모드를 지원했는가 보다.
VGA는.. mode X라고 해서 320*240, 400*300 같은 해상도를 지원했다. 마이클 압래시라는 사람이 이런 걸 발견하고, 도스용 퀘이크에서 이걸 적용해서 많이 알려졌다.

- VGA는 그 이전의 CGA,EGA와 달리.. 그래픽 카드와 모니터를 연결하는 단자가 D-sub라고 원래 아날로그 기반이었다. 그 시절의 기술로 그 해상도와 색상, 주사 횟수를 구현하려다 보니 디지털로는 버거움을 느꼈던 것 같다. 하지만 후대에는 DVI나 HDMI 단자가 등장하면서 다시 디지털로 돌아왔다.
그 시절에 주류였던 두툼한 브라운관 모니터도 아날로그 신호와 더 친했지 싶다. 브라운관은 아무 해상도에나 픽셀 뭉개짐 없이 유동적으로 대응 가능한 유일한 디스플레이 기술이다.

- 각 그래픽 모드를 소프트웨어적으로 흉내 내어 주는 램 상주 프로그램이 있었다. simcga라든가, msherc 따위.. 단, simvga는 공식 프로그램이 아니라 낚시 악성코드였다.;;

- 1988년에 출시됐던 Splash! (Spinnaker software)라는 그래픽 에디터는 최신 VGA 저해상도 256색 그래픽을 채용한 거의 초창기 프로그램이었다. VGA는 1987년에 출시됐고, 그때는 아주 값비싼 최신식 그래픽 카드였으니까..
참고로 87~88년이면.. C++을 C로 전처리 거치지 않고 직통으로 번역하는 컴파일러가 업계 선구자에 의해 거의 최초로 등장했던 시기이기도 하다. 업계에서는 C++은 아직 듣보잡이었으며, C와 어셈블리가 당연시됐었다.

- 퀵베이식에서는 SCREEN 13 한 줄만으로 VGA 256색 모드로 바로 진입 가능한 반면, 그 당시 볼랜드의 개발툴(Turbo C/Pascal)이나 파워베이식은 그 당시 게임 프로그래밍에서 필수였던 이 mode 13h에 대한 지원이 유난히 인색했다. 그 이유를 난 아직도 모르겠다.

- 이 VGA 이후로 800*600 16색이라든가, 640*480 256색, 1024*768, 심지어 트루컬러 같은 발전된 모드는 IBM에서 더 중재를 하지 않고 업계 재량으로 넘어갔다. 사실, IBM은 XT/AT 이후에 80386부터는 표준 PC에도 더 관여하지 않고 손을 놨고, 운영체제 역시 OS/2가 Windows에 밀리면서 PC 시장과는 점차 인연이 멀어지게 됐다.

3. 전통적인 컴퓨터의 명가

  • 크레이: 슈퍼컴
  • IBM: 메인프레임
  • : 워크스테이션??
  • HP: 서버

이들과 달리, PC는 뭔가 독보적으로 접수하고 있는 업체가 없다. 마소와 인텔?? 얘들은 물론 컴퓨터 완제품이 아니라 CPU와 운영체제 제조사이니 위의 예들과는 성격이 좀 다르다. 이제는 슈퍼컴이나 워크스테이션 같은 컴퓨터의 영역이 PC에 많이 흡수되기도 했고..

4. 하드웨어의 발전

(1) 마우스 포인터: 그림이 계속 그려지고 있는 곳에 마우스 포인터를 가져가도 포인터가 깜빡거리지 않게 됐다.
이건 뭐 30년 전 Windows 3.x 시절부터도 비디오 드라이버를 적절하게 잡으면 실현됐던 사항이다. 그 시절의 그래픽 카드도 마우스 포인터 정도의 스프라이트를 하드웨어 차원에서 직통 처리하는 기능은 제공했기 때문이다.
Windows 2000부터는 그래픽 카드를 잡지 않은 VGA 16색 안전 모드에서도 마우스 포인터가 깜빡거리지 않기 시작했다. 9x는 그렇지 않았다.

(2) 사운드: Windows 98쯤부터 여러 프로그램에서 사운드를 동시에 재생할 수 있게 됐다. 그 전에는 정말 믿어지지 않지만 사운드도 무슨 파일처럼 한 프로그램에서 열면 다른 프로그램에서 접근할 수 없는 리소스였다.;; 멀티웨이브 믹싱이 지원되지 않았던 것이다.

(3) 화면: print screen 키를 눌러서 동영상 재생 화면도 캡처가 가능해졌고, 일반 그래픽과 아무 차이가 없어졌다. 이건 나름 Windows Vista에서부터 실현된 기술 발전이다.

Posted by 사무엘

2023/01/14 19:35 2023/01/14 19:35
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2113

1. 성능과 알고리즘

(1) 현실의 퀵 정렬 알고리즘 구현체는 구간의 크기가 일정 기준 이하로 작아지면 그냥 O(n^2) 복잡도의 단순한 삽입 정렬로 대체하곤 한다. 그게 더 효율적이기 때문이다.

(2) 균형 잡힌 트리는 삽입, 탐색, 삭제가 모두 O(log n)의 복잡도로 되는 매우 유용한 자료구조이다. 그렇기 때문에 단순히 메모리 레벨의 set이나 map 컨테이너뿐만 아니라 파일 시스템이나 DB 같은 디스크 레벨에서도 쓰인다.
요즘 아무렇게나 DIR을 해도 파일 목록이 언제나 ABC 순으로 정렬되어 출력되는 이유는.. NTFS 파일 시스템이 내부적으로 이런 트리 구조를 사용하기 때문이다. (반면, 과거의 재래식 FAT는 연결 리스트 기반이어서 파일 목록의 정렬이 보장되지 않음)

단, 디스크 레벨에서는 단순한 이진 나무가 아니라, 이를 변형하여 한 노드에 딸린 자식이 좀 더 많은 B+ 같은 트리 구조가 쓰인다. 왜냐하면 디스크는 메모리보다 입출력 속도가 훨씬 더 느리며 랜덤 지점 탐색에 취약하기 때문이다.
그래서 한 노드 안에서 선형 검색을 좀 더 하더라도, 노드 하나를 탐색하고 읽는 횟수를 줄이는 게 더 이득이다. 다만, 이런 이념도 재래식 하드디스크가 아니라 플래시 메모리에서는 유효하지 않을 수 있다.

(3) 한 번에 한 스레드만 접근 가능해야 하는 코드가 있다면 보통 그 구간을 critical section이나 뮤텍스 따위로 둘러싼다.
그런데 이것도 "어? 다른 스레드가 이미 들어가 있네? 그럼 우리는 닥치고 바로 대기".. 이렇게 단순무식하게 하는 것보다,
loop을 돌면서 busy waiting, polling, spin lock을 n번만 더 시도해 보고 "그래도 여전히 다른 스레드가 나가지 않았으면 그때 대기 타자" 이런 유도리 전략이 좀 더 효율적일 때가 있다.

왜? 대기를 탔다가 깨어나는 작업 자체가 사용자 모드에서 커널 모드로 들어갔다가 나오는 것이며, 수천 사이클에 달하는 CPU 오버헤드를 요구하기 때문이다. 대기하고 있는 스레드는 CPU를 먹지 않지만, 대기 상태로 들어가거나 깨어나는 출입 과정은 공짜가 아닌 것이다.

더구나 요즘 컴퓨터는 코어가 여럿 있기 때문에 한 스레드에서 아주 잠깐 무식한 busy waiting을 하더라도 그게 타 스레드의 실행 성능에 영향을 주지 않는다. 그럴수록 대기 진입을 한 템포 늦춰서 신중하게 하는 게 가성비가 더 커진다.

일상 생활에다 비유하자면, 여러 잡다한 물건을 들고 있어서 무거운 채로 엘리베이터나 버스를 기다리는 것과 비슷하다. 이걸 바닥에 완전히 내려놓아 버렸다면 팔이 힘들지는 않지만, 그걸 다시 집어드는 것도 굉장히 번거로운 일이 된다. 그러니 버스나 엘리베이터가 수 초 안으로 금방 온다면 그냥 그 물건들을 들고 기다리고 있는 게 더 낫다.

이렇듯, 컴퓨터에서는 성능을 최대화하기 위해 한 방법만으로 만족하지 않고, 상황에 따라.. 특히 아주 제한된 문맥에서는 통상적으로 비효율적이라고 알려진 무식한 방법까지도 동원한다는 걸 알 수 있다. 스타로 치면 여러 유닛을 조합하는 것과 같다.

2. 자원의 회수

식물은 죽어서 말라 비틀어진 잎· 줄기나 썩은 열매 따위의 처리가 아주 간편한 축에 든다. 땅에 파묻기만 하면 거름이 되고 도로 자연으로 돌아가고 구성 물질이 회수된다.
뭐, 동물도 궁극적으로 그렇게 되기는 한다. 하지만 사체가 분해되는 과정이 식물보다 훨씬 더 더럽고 끔찍하고 더 오래 걸리는 편이다.

이런 물질의 순환은 뭔가.. 가상 머신에서 GC에 의해 자동 관리되는 메모리 같다는 생각이 들지 않는지?
본격적으로 물질의 메모리 누수가 문제되기 시작한 건 인류가 자연이 제대로 감당하지 못하는 플라스틱 같은 고분자 화합물을 만들어서 쓰기 시작하고부터이다. 그리고 반감기가 끔찍하게 긴 방사능 물질도 이런 범주에 든다고 볼 수 있겠다.

뭐, 썩지 않는 물질이 다 문제이고 골칫거리는 아니다. 수도관 같은 건 절대로 부식되거나 썩지 않는 재료로 만들어서 수백, 수천 년은 써야 할 테니 말이다.

3. 코드

(1) 우리나라의 모든 법조문들이 몽땅 github에 올라오고, 전체 개정 이력을 Show log 명령을 통해서 조회하고 싶다는 생각이 든다. 전철 노선도 같은 물건도 마찬가지이다.

(2) 대학교 컴터공학과 학부에서 시스템 프로그래밍 시간에 MIPS 어셈블리어 갖고 깨작깨작 실습하는 건.. 육사에서 승마나 백병전 총검술 잠깐 맛보기 하는 것과 정확하게 대응하지 싶다~ ㅋㅋㅋ
학교에서 뭔가 C/C++, Java, Python 같은 실용적인(?) 언어 말고 뭔가 비현실적인 언어를 다뤄 보는 게 이렇게 어셈블리어 같은 레거시 계열, 아니면 엄청나게 순수한 이론 이상을 추구하는 함수형 언어 계열.. 이렇게 둘로 나뉘는 듯하다.

(3) 자동차 취급설명서는 소스 코드 곳곳에 들어서 있는 조건부 컴파일의 완벽한 예시로 보인다. * 표시가 돼 있는 각종 선택사양들.. 그리고 악보의 음표 위에 붙은 각종 나타냄말? 스타카토, 스타카티시모 이런 건 매크로의 예시이다.
악보는 각종 반복과 분기가 복잡하게 꼬이면 흐름이 진짜로 어지간한 프로그램 코드처럼 바뀌기도 한다.

(4) 성경에서 '주의 책', '(어린양의) 생명책' 같은 상상 속의 거대한 책이 언급된 걸 보면.. 예수 믿는 컴터쟁이들은 하늘나라에 있는 거대한 데이터베이스와 DB 서버 정도는 떠올릴 수 있을 것 같다.
물론 인간이 만든 컴퓨터는 신의 주요 성품 중 하나인 '무한, 영원'이라는 걸 절대로 구현하지 못하는 물건이다. 그러니 DB 드립은 마치 "김 성모 스타일의 성경 이야기"만큼이나 그냥 웃자고 늘어놓는 말일 뿐이다.

(5) 요한복음의 마지막 구절인 "이 세상이라도 예수님의 행적을 기록한 책들을 다 담지 못할 것이다"는 정보량과 관련된 언급이다. 그리고 삼손의 수수께끼 놀이는 정보 보호· 보안과 관련된 통찰을 주는 이야기이다.

4. 자동과 수동

요즘 수동 변속기 차량을 몰 줄 아는 사람이 갈수록 드물어지듯, 컴터 업계도 C/C++처럼 메모리를 수동으로 관리하는 저급 언어를 제대로 다룰 줄 아는 사람이 갈수록 드물어지는 것 같다.
직장에서 부사수로 들어온 어린 신입 개발자에게 사수가 메모리 leak이라는 개념을 알려주는 게 굉장히 뜻밖이고 놀라워 보였다.

하긴, 공대 1학년의 기초 필수 프로그래밍 과목에서 가르치는 언어도 초창기엔 C/파스칼이다가 나중에 Java를 거쳐 지금은 파이썬이지 않은가. 프로그래밍을 위한 전산학적인 소양하고, C나 컴퓨터 특유의 지저분한 감각이랄까, 이 둘이 영역이 완전히 일치하지는 않기 때문이다.

고깃집의 경우, 직원이 알아서 고기를 다 썰고 구워 주는 곳은 자동 변속기-_- 같고, 손님이 직접 고기를 얹고 굽고 자르고 뒤집어야 하는 곳은 수동=_=;;에 해당된다. 후자보다는 전자가 아무래도 마음 편하게 고기를 먹을 수 있지만.. 인건비가 추가되어 고기값이 더 비쌀 것이다.

5. 전체 리셋

컴퓨터 시스템을 날리는 방법으로 sudo rm -rf 라든가=_= Windows의 레지스트리 날리기, 시스템 디렉터리 날리기 같은 게 있다.
운영체제가 아닌 DB에서는 delete * 내지 drop table 같은 파괴적인 쿼리가 있다. 손가락 까딱 잘못 건드려서 회사 재산과 관련된 DB를 날렸다간 짤리는 정도를 넘어 손해 배상 소송을 당할 수도 있을 것이다.

그런데 국가로 치면.. 헌법 제1조가 바뀌거나 날아가는 게 그런 급의 파괴적인 사건일 것이다. 헌정 체제가 쿠데타로 인해 싹 뒤집히거나, 아니면 전쟁에서 지기라도 해서 외적이 자국 행정부를 완전히 접수했을 때에나 있을 수 있는 일이다.

우리나라의 경우, 옛날에는 "대한민국은 민주공화국이다" 같은 몇몇 조항은 개헌조차 아예 영원히 불가능한 조항으로 못 박으려는 시도가 있었다. 컴퓨터로 치면 운영체제의 작동과 직접적인 관련이 있는 일부 시스템 파일을 절대 변조· 삭제할 수 없게 특수하게 보호하는 것과 비슷하다고 하겠다(업데이트 받을 때만 빼고).

하지만 법리적으로 볼 때 그렇게까지 할 필요는 없기 때문에 개헌 불가 조항 같은 건 과거의 해프닝으로 끝났다. 그리고 지금 6공화국 헌법은 그렇잖아도 개헌이 너무 어려운 형태가 된 감이 좀 있다.;; 과거에 널뛰기 하듯이 수시로 개헌하던 관행을 없애고 싶었던 심정은 이해가 가지만 지금은 그것 때문에 미래까지 발목이 잡힌 것 같다.

6. C++ export와 우주왕복선

2000년대 초에.. EDG 같은 일부 C++ 컴파일러 개발사에서는 희대의 흑역사 표준 기능이던 export를 구현하느라 상상을 초월하는 삽질을 했던 거랑,
NASA에서 2003년의 컬럼비아 우주왕복선 사고 이후에 이제는 우주왕복선을 띄울 때마다 옆에 구조용 예비 기체까지 같이 대기시키면서 정말 눈물겨운 삽질을 잠시 했던 것..
둘이 시기도 비슷하고 심상이 뭔가 묘하게 비슷하게 느껴진다.

전자는 지금까지 C++ 표준에 새로 추가되었던 복잡한 기능들과는 구현 난이도가 차원이 달랐다. 기존 언어 구조의 근간을 다 뒤엎어야 하는 헬 수준이었는데, 그렇다고 템플릿의 모듈화를 제대로 실현해 주는 것도 아니었다. 이건 정말 백해무익에 가까운 미친 짓이었다. 결국 export는 2010년대 C++11에서는 완전히 삭제되었다.

우주왕복선에다가 구조 미션까지 추가한 것 역시.. 셔틀 한 대에다가 사람을 11명이나 태우는 것(기존 승무원 7 + 구조 요원 4), 안 그래도 3대밖에 없는 셔틀을 매번 2대나 세팅해야 하는 것, 묘기에 가까운 어렵고 위험한 기동으로 조난 당한 셔틀에 접근해서 사람을 구조하는 것..
살인적인 비용 대비 사람을 살릴 가능성도 별로 없는 미친 짓이었다. 다행히 이 미션이 실전에서 쓰인 적은 없었으며, 우주왕복선 역시 C++11과 비슷한 시기인 2011년에 완전히 퇴역했다.

7. 나머지

(1) 생물은 번식할 때 동물과 식물을 막론하고 가까운 혈통끼리 교배하지 말고, 최대한 먼 촌수끼리 다양하게 섞여서 교배해야 유전병 없이 건강한 후세가 태어나고 안전하다고 여겨진다. 유전적 다양성이란 게 중요하다.
이런 걸 뭔가 숫자의 특성으로 표현하면 해시값의 충돌이 안 나는 것, 셸 정렬이 빠르게 수행되는 간격 수열을 구하는 것(무식하게 2^n에서 절반씩 줄이는 건 최악), 퀵 정렬의 pivot 중간값을 적절하게 잘 고르는 것에 대응하는 것 같다.

(2) 자동차나 자전거 운전하다가 상대방과 부딪칠 것 같아서 한쪽으로 피하는데..
골때리게도 상대방도 내가 피하는 방향과 같은 방향으로 피하고, 이 상황을 탈피하지 못해서 결국 부딪히는 경우가 있을 수 있다.
이런 게 머신러닝이나 방정식 근 찾기에다 비유하자면 처음에 시작점을 잘못 잡고 학습을 잘못 시켜서 최적해로 수렴을 못 하고 삼천포로 빠진 것과 비슷해 보이는 상황이다. 아니면 데드락을 극복하지 못했거나.;;.

(3) 옛날, 1955년쯤에 중공의 마오 주석께서는 하늘을 향해 삿대질을 하며 "저 새는 해로운 새.." 아니, "참새는 해로운 새"라고 교시하시였다는데..
1968년쯤에 네덜란드의 전산학자 다익스트라는 ACM 저널을 통해 "GOTO Considered Harmful".. 즉, 스파게티 코딩이 해롭다고 저격했었다. 오늘날은 저 두 말투가 모두 밈..처럼 쓰이고 있다. ㅋㅋㅋ

Posted by 사무엘

2022/07/11 08:35 2022/07/11 08:35
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2041

1. 포니, 봉고, 엑셀

국산차 중 현대 포니는 동급 배기량 중에서는 전무후무 유일하게 후륜구동이었던 승용차이다.
기아 봉고는 뒷바퀴가 트럭처럼 복륜 형태였던 유일한 소형 승합차이다.

봉고는 한때는 승합차 이름이었지만 지금은 트럭 이름으로만 남아 있다.
엑셀은 한때는 승용차 이름이었지만 지금은 스프레드시트 프로그램의 이름으로만 남아 있다. ㄲㄲㄲㄲㄲ
워드퍼펙, 로터스 1-2-3, dBASE 같은 업무용 프로그램들은 Windows 시대에 적응하지 못하고 도태되고 사라졌다.;;

2. 위험한 데이브

우한 괴질 덕분에 30여 년 전 초딩 시절에 했던 ‘위험한 데이브’ 게임에 새겨져 있던 이 알파벳 이니셜을 다시 주목하게 되는구나~!

사용자 삽입 이미지

(인터넷 좀 뒤져 보니, 저건 PC Arcade를 의도한 거였다고 한다.;;)

저 시절에(1990년경) PC용 게임들은 본격적으로 시작하기 전에 그래픽 모드를 CGA (4색), EGA (16색), VGA (256색) 중 하나 선택하는 게 관행이었다. 한번 선택한 뒤에는 변경할 수 없었고, 딱히 변경할 필요도 없었다.
그런데 저 데이브는 굉장히 이례적이게도, 게임 진행 중에 그래픽 모드를 자유자재로 변경할 수 있었다. 하던 게임을 중단하지 않고 말이다.

사용자 삽입 이미지
(게임 중에 F2를 누르면 언제든지 나타나는 환경설정 화면. 어라? 이미 PC-arcade라는 단어가 있었구나~!!)

그게 가능한 게임은 내가 아는 도스용 수백여 종의 게임 중에 진짜 쟤가 유일한 것 같다~! 신기하지 않은가?
비슷한 시기의 Windows 3.x만 해도 그래픽 모드, 색상, 해상도 따위를 변경한 뒤에는 운영체제를 재시작해야 했는데 말이다. 지정도 제어판이 아니라 설치 관리자를 통해서 해야 했다.

3. 메신저

과거의 icq, msn (훗날 WLM), 스카이프, 그리고 요즘 카카오톡에 이르기까지..
기업에서 만들면서 무료로 뿌리는 메신저 프로그램은 세월이 흐를수록 엄청나게, 불필요하게 덩치 커지고 무거워지는 게 필연적인 수순인 것 같다.
그도 그럴 것이 평범한 채팅 기능만 제공해서는 수익이 나질 않으니 어떤 형태로든 부가적인 서비스를 집어넣어야 하기 때문이다.

카카오톡은 기존 대화 데이터들이 쌓이고 프로그램 자체도 버전업을 거듭하다 보니 예전에 비해 뜨는 데 걸리는 시간이 정말 눈에 띄게 길어졌다. 뭐, 본인은 수 년 이상 묵은 굉장한 구닥다리 전화기를 사용한다는 것도 감안할 점이긴 하지만.. 거의 20~30초씩 걸린다.
PC용 프로그램이었다면 일개 메신저가 스플래시 화면이라도 좀 있어야 할 것 같다.;;

더구나 과거엔 공공장소 입장용 QR 코드를 생성하거나 백신 접종 정보를 불러오는 데도 비슷하게 시간이 너무 오래 걸려서 이것도 불만 사항이었다. 지금이야 백신패스는 아련한 옛날 이야기가 됐지만.. 그래도 프로그램이 최적화와 관련해서 좀 아쉬운 면모가 있다.

4. 블리자드

블리자드가 2018년 이래로 그 누구도 생각하지 못한 빠른 속도로 망조 들고 몰락하고 있는 것이 놀랍다.
무려 2000년경, "환상의 테란"이라는 PC통신(!!) 소설에서는 "서기 2020년, 블리자드는 스타라는 걸작 게임만을 남긴 채 망해 버렸고 게임의 소스 코드는 공개되지 않았으며, 사장은 어느 열받은 테란 플레이어에게 살해 당했다"라는 정말 비현실적인 설정을 제시했었다.

디아블로, 스타, 워크래프트라는 불멸의 명작 대작을 내놓으며 승승장구하던 게임 개발사가 망할 거라고는 그 시절에 누가 상상이나 했겠는가? 그 뒤로도 WoW에, 오버워치 이러면서 2010년대까지도 잘 나가지 않았던가?
그랬는데 지금이야 뭐.. 회사 창립자인 사장이 살해...;;까지는 아니지만 물러났고, 스타를 만들었던 핵심 개발진들이 죄다 퇴사하고 회사를 따로 차리는 지경이 됐다. 기존 스타크래프트는 1(리마스터)이고 2고 간에 유지 보수가 도저히 안 되는 막장 상황이 된 건 확실해 보인다.

우와, 그 명작인 스타크가 개발사로부터 버림받는 지경이 됐다니.. 하긴, 유명한 것 대비 회사 입장에서의 수익성이 너무 없어지긴 한 것 같다.
이렇게 되지 않으려고 국내의 온라인 게임 개발사들은 처음에 돈독 올랐다고 욕 먹는 한이 있어도 정액제니 부분 유료화니 하면서 사용자에게서 지속적으로 돈을 걷는 체계를 만든 것 같다. 한 번만 돈 내고 끝인 패키지가 아니라 말이다.

그랬는데 블리자드가 2022년 초에 마소에 인수됐다. 마소는 게임 제작사들의 재량을 존중해 주는 관대한 기업이니 블리자드의 옛 명성을 되찾아 줄 것을 기대해 본다.
하긴, 왕년에 Doom과 Quake를 개발했던 id조차도 마소에 인수돼서 그쪽 계열사가 된 지 오래다. id를 인수하고 싶어했던 빌 게이츠의 오랜 소원은 빌이 은퇴한 뒤에야 결과적으로 성취됐다.

그 마소에서도 알다시피.. 2010년대에 경영진이 싹 바뀌고 컴퓨팅 시장의 판도가 많이 바뀌었던 시절에 Windows 8과 관련해서 삽질이 유난히 잦았다. Windows 10은 초창기에 예전의 마소답지 않은 온갖 버그들이 난무했었다.
MFC처럼 수십 년 묵은 고인물 썩은물은 마소 내부에서도 안 쓸 뿐만 아니라, 코드 구조를 다 꿰뚫고 유지 보수 가능한 사람이 거의 안 남았다나 어쨌다나.. MFC가 그러한데 하물며 딱히 작업할 것도 없고 10년 넘게 변화가 없는 한글 IME 코드의 관리 인력이야 두 말하면 잔소리이지 싶다.

소프트웨어 개발사는 핵심 프로그래머가 교체되더라도 제품 코드에 대한 노하우가 단절 없이 전수되고 코드의 유지 보수가 가능하도록 정말 노력해야 할 것 같다. 일례로 각종 주석과 문서 작성을 게을리하지 말아야 할 것이다.
남이 도무지 읽을 수 없는 스파게티 코드, 난독화 코드를 잔뜩 짜 놓고는 "이 코드는 나 말고는 아무도 의미를 알 수 없어~" 이렇게 버티는 건.. 반칙이며 알박기나 마찬가지일 테니 말이다.. =_=;;

Posted by 사무엘

2022/06/30 08:36 2022/06/30 08:36
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2037

1. 증기 기관과 컴퓨터

20세기 중반에 전자식 컴퓨터나 그 전신뻘의 물건이 최초로 개발되어서 수행했던 임무는 탄도 계산이나 암호 해독 같은 군사 관련 일이었다. 게임이나 무슨 수학자 덕질 같은 용도가 아니었다. 인터넷도 맨 처음엔 생각보다 굉장히 군사· 안보 상의 목적과 필요 때문에 개발되었다는 것을 알 만한 분은 아실 것이다.

그리고 옛날에 증기 기관이란 게 최초로 개발되어서 투입된 용도는.. 기억하시는가? 무슨 군사나 교통수단이나 면직물 가공 기계가 아니라, 탄광 내부에 찬 지하수를 빼내는 펌프의 가동이었다. 즉, 자신이 석탄을 소모하면서 역으로 석탄을 캐는 일을 도와줬던 것이다. (물론 자기가 소모하는 것보다 훨씬 더 많은 석탄을 캐는 걸..)
그렇게 태동했던 기계가 하나는 산업 혁명을 견인했고 다른 하나는 정보화 시대라는 걸 만들었다니 참 격세지감이다.

2. 도트 프린터와 비트맵 폰트

21세기, 2020년대를 찍고 있는 요즘은 자그마한 종이 쪼가리에 찍혀 나오는 영수증이나 카드 명세서, 승차권/탑승권, 주문 번호표, 관공서 차례 대기 번호표조차도 다 열전사 같은 비충격식 프린터로 인쇄되는 세상이다.
하지만 쌍팔년도의 잔재인 찌익~ 찍 도트 프린터의 출력 결과물을 아직까지 생생히 볼 수 있는 곳은 단연 은행이라 하겠다. 독보적이고 유일하다. 이게 개인적으로 매우 매우 흥미롭고 신기하게 느껴진다~!

사용자 삽입 이미지

통장의 책장을 넘겨가며 거래 내용을 인쇄한다거나, 혹은 이미 만들어져 있는 은행 특유의 각종 양식 문서의 일부란에 문자와 숫자를 찍는 용도로는 재래식 도트 프린터가 여전히 유용한가 보다. 물론 전자 통장, 전자 문서 때문에 예전에 비해서 필요성이나 활용 빈도가 많이 줄어들긴 했지만 말이다.

사용자 삽입 이미지사용자 삽입 이미지

도트 프린터가 독특한 이유는 찍혀 나온 글자의 자형, 즉 폰트부터가 독특하기 때문이다.
이런 도트 프린터는 해상도가 그리 높지 않았기 때문에 겨우 본문용 크기에서 산돌이니 윤디자인이니 하는 상업용 폰트를 보기 좋은 퀄리티로 찍을 수 없다. 그 대신 그 저해상도에서 그럭저럭 보기 좋게 특화된 전용 비트맵 명조/고딕 같은 폰트가 쓰인다.

지금 Windows의 굴림/바탕/돋움 같은 폰트만 봐도, 대략 19포인트까지는 이런 비트맵 버전이 쓰이다가 20포인트부터는 일반적인 윤곽선 버전이 투입되는 걸 확인할 수 있다. 이런 게 저해상도 프린터에서는 인쇄용으로도 쓰인다는 것이다.

저해상도 비트맵 폰트를 종이 인쇄를 통해 볼 수 있는 곳은 은행이고, 화면 형태로 볼 수 있는 곳은 단연 각종 LED 전광판일 것이다. 하지만, 이 분야도 해상도와 색상이 증가하면서 윤곽선 폰트(= 출판물용 고퀄 폰트)로 대체돼 가고 있다.

아날로그 숫자 카운터가 원래 주유소 주유기, 테이프 재생기의 구간, 자동차 계기판의 거리계 등 여러 곳에서 볼 수 있다가 지금은 싹 다 사라지고 수도· 전기· 가스 검침기에서나 볼 수 있는 것과 비슷한 현상 같다.
많이 없어지긴 했지만, 완전히 멸종 급으로 자취를 감춘 건 아니라는 것이다. 공중 전화처럼 말이다.

나 역시 비트맵 폰트의 끝물 마지노 선을 지키는 프로그램을(날개셋 편집기..) 보유하고 있는 관계로.. 이런 비트맵 폰트를 주위에서 보면 괜히 반갑다. 컴퓨터라는 게 처음 등장하던 시절에 쓰였던 투박한 추억의 폰트들을 최대한 복원해서 내 프로그램에서 재생해 보고 싶다.

그나저나, 요즘은 민증이나 면허증 같은 신분증들도 온통 전산화됐기 때문에 실물의 필요성이 많이 없어졌다. 잃어버렸을 때의 타격도 많이 덜하다.
하지만 현물 실물의 중요성이 여전히 가장 크고 절대로 잃어버려서는 안 되는 개인 증서는 아무래도 여권이지 싶다. 당연히 외국 나가 있는 중에 말이다. 신원 조회라는 게 전국구 급으로는 수월하게 되지만 그게 세계구 급으로 되는 건 아니기 때문일 것이다. 세계가 무슨 음모론자들의 주장처럼 세계 단일 정부로 가는 건 말처럼 호락호락 쉽게 가능하지 않다.;;

여권도 카드가 아니라 통장 같은 수첩 형태이고, 도트 프린터로 찍은 기록들이 덕지덕지 추가될 것 같은데 그래도 얘는 통장보다는 인쇄 스타일이 옛날식이 아닌 것 같다.

3. 일반인 소비자가 보는 것만이 전부가 아님

(1) 증기 같은 외연 기관은 교통수단의 동력원으로는 진작에 퇴출됐다. 허나, 외연 기관 자체는 증기 터빈의 형태로 지금까지도 엄연히 현역이다. 지금 세계에서 생산되는 전기의 압도다수는 증기 터빈 발전기를 돌려서 생산된 것이다. 화력이든, 원자력이든.

(2) 선박은 비행기에 밀려서 대륙 간 장거리 여객 교통수단으로는 완전히 퇴출됐다. 그러나 화물을 살펴보면?? 선박이 없이는 세계 물류가 돌아갈 수 없다. 운하가 하나 틀어막히기만 해도 어떤 일이 벌어지는지를 우리는 얼마 전에 목격한 바 있다.

(3) 인터넷을 통해 지구 반대편으로 정보 전송이 가능한 것은 압도다수가 인공위성이 아니라 해저 케이블 덕분이다.

(4) 8비트 CPU는 성능이 너무 떨어지기 때문에 사람이 직접 다루는 PC나 게임기용으로는 수십 년 전에 진작에 퇴출됐다. 그러나 그 정도로 높은 성능이 필요하지 않고 최소한의 제어만 하면 되는 기기들.. 밥솥, 자판기, 전광판 이런 데서는 저렴한 가격에 낮은 전력 소모 등 유용한 구석이 많다.
그렇기 때문에 임베디드용으로 세계에서 여전히 수십억 개씩 생산되고 있다~! 다른 분야에다 비유해 보면 거의 척추동물(PC)과 무척추동물(임베디드..)의 개체수 차이와 비슷할 정도이다.;; 오히려 이도 저도 아니고 어중간한 16비트가 콩라인이 됐을 뿐..

(5) 오늘날 카세트 테이프는 컴퓨터에서나 오디오에서나 모두 한물 가고 퇴출됐다. 그러나 테라/페타바이트 급의 초 거대 용량의 백업 보관용으로 가장 우월한 저장 매체는 여전히 자기 테이프이다. 물론 이런 건 일반인이 가정에서 취급하는 급의 물건은 아니다.

(6) 컴퓨터의 통신 수단으로서 구닥다리 전화선과 모뎀은 진작에 퇴출되었다. 하지만 서류를 주고 받는 용도로 전화선 기반의 팩시밀리는 여전히 건재하다.
디지털이나 인터넷과 동떨어져 있지만 고유한 쓸모가 있기 때문이다. 어떤 가게가 지금 영업을 하는 중인지 알아보는 제일 쉽고 확실한 방법은 카톡이고 이메일이고 나발이고 필요 없이, 그냥 전화를 걸어 보는 것이듯이 말이다.;;
복사기, 스캐너, 팩스, 프린터는 종이를 다루는 복합기로 싹 통합해 버리기에 딱 좋아 보인다.

4. 저렴해지는 것, 비싸지는 것

사용자 삽입 이미지

그랜저가 30년 전이나 지금이나 똑같이 3~4천만 원대인 걸 아시는가..??
배기량과 가격만 비슷하지 엔진 성능이나 효율, 편의 시설은 30년 전과 지금이 쨉이 안 될 것이고, 물가 상승도 쨉이 안 될 것이다.
하지만 어떻게 지내냐고 누가 물었을 때 그랜저로 답하기가 지금이 훨씬 더 쉬워진 셈이다. 물론 그 대신, 그랜저보다 더 비싼 고급차가 나오기도 했고 말이다.

1990년대 초엔 486 컴터 한 대가 3백~5백만 원이었다. 당연히 그 시절 물가 기준으로. -_-
버스비, 우유· 라면처럼 원래부터 소액이던 것은 가격이 몇 배로 무섭게 뛰었지만, 옛날에 왕창 비쌌던 고급 기계는 가격이 놀라울 정도로 변하지 않거나 더 싸졌다.

컴퓨터는 CPU뿐만 아니라 메모리도 Windows 95가 처음 나왔던 시절에 4MB를 추가로 장착하는 데 십몇만 원 이랬었다.
이러니 PC 환경에서 16비트 도스를 좀체 졸업할 수 없었다. 가상 메모리를 구현하고 현대적인 32비트 운영체제를 돌리려면 메모리를 관리하는 데 드는 메모리도 필요하고 도스보다 훨씬 고사양의 컴터가 필요하기 때문이다. x86이 구닥다리 비효율을 감수하고라도 조밀조밀 CISC 방식으로 만들어진 건 메모리를 조금이라도 더 아끼기 위해서였다.

그런데 1990년대 말~2000년대 초 사이에 메모리가 갑자기 64, 128, 256MB 이렇게 순식간에 뻥튀기 되기 시작했다. CPU 클럭 속도만 뻥튀기 된 게 아니었던 거다. 이렇게 메모리가 값싸고 풍족해진 덕분에 그 당시 Windows 9x 계열의 퇴출이 더욱 앞당겨지고 2000/XP 같은 NT 계열이 대세가 될 수 있었다!
메모리 반도체의 본좌인 삼성 전자에서 그 당시에 갑자기 외계인 고문과 공밀레를 열나게 시전해서 기술 혁신을 이뤄낸 건지는 잘 모르겠다. 무어의 법칙뿐만 아니라 황의 법칙도 거론될 정도였으니까..

세월이 지나도 변하지 않는 동안 외모처럼, 어떤 분야엔 세월이 지나도 변하지 않는 가격이라는 것도 있는가 보다. 이런 변화가 무엇을 의미하는지 한 번쯤 곱씹어 볼 필요가 있다.

5. 멀티미디어 기능

옛날에 PC가 성능이 뛰어나지 못했을 때는.. 텍스트 모드에서 한글· 한자를 찍기 위해서(!!!), 부동소수점 연산을 더 빠르게 하기 위해서, '삑삑'이 아닌 레알 사운드를 듣기 위해서 별도의 카드를 꽂고 애드온을 컴퓨터에다 장착해야 했다. 뭐, 상당수는 쌍팔년도 얘기이지만 1990년대 초중까지만 해도 동영상 재생 정도는 별도의 MPEG 카드를 꽂아서 해야 했다. 그러나 지금은..

  • 그래픽과 사운드는 기본적인 수준이야 CPU 메인보드에 이미 다 기본 내장됐다. 저 분야에서도 SoundMAX인지 인텔 비디오인지 하면서 Intel이라는 단어가 슬금슬금 보이기 시작했다.
  • 이제는 동영상 재생이 아니라 컴퓨터 화면을 실시간으로 부드럽게 녹화할 때에나 캡처보드 같은 별도의 카드가 필요한 듯하다. 물론, 평범하게 컴터를 다루는 모습이 아니라 복잡한 게임 장면을 녹화하는 것 말이다.
  • 아니면 GPU까지 빡빡 혹사시키는 high-end급 온라인 게임을 할 때, 머신러닝을 시킬 때..

  • TV 수신 카드는 요즘도 수요가 있는지 모르겠다.
  • 모니터와 텔레비전이 모두 디지털에 LCD 기반으로 바뀌다 보니, 오랫만에 켰을 때 과거의 브라운관 수상기처럼 화면이 서서히 밝아지고 상이 커지는 모습도 볼 일이 없어져 있다. 이런 모션은 이제 프로젝터를 켤 때에나 가끔 보는 것 같다.

Posted by 사무엘

2022/06/08 08:35 2022/06/08 08:35
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/2029

1. 숫자를 표현하는 방식

20세기 중반에 컴퓨터가 아직 진공관 기반으로 만들어지던 시절에는 전기식이 아닌 전자식으로 바뀐 것뿐만 아니라 10진법 대신 순수 2진법을 사용하기 시작한 게 큰 전환점으로 여겨진다. 그게 더 기계 지향적이고 직관적인 설계이기 때문이다.

이건 사람으로 치면 별도의 교육을 통해 암산 때 머릿속에서 아라비아 숫자 대신 주판알을 떠올리는 것과 비슷하지 않을까 싶다. 아라비아 숫자는 문자로서 실용적인 기능도 겸하려다 보니, 숫자의 본질과 연산에 직관적으로 대응하는 체계가 아니기 때문이다.
심지어 주판법에는 선주법과 후주법이 모두 존재한다. 이건 컴퓨터에서 big/little endianness와 거의 동일한 개념인 것 같다.

2. 색공간과 실제 공간

우리가 사는 현실의 공간은 길이· 너비· 높이라는 xyz 세 축, 즉 3차원이라고 여겨진다.
그런데 우리에게 시각을 인지시켜 주는 색이라는 것도 어떤 형태로 축을 나누든.. RGB건 HSL이건 CMY건 결국 3개의 축으로 이뤄진다는 게 시사하는 바가 커 보인다.
가령, 색에서 hue라고 불리는 빨주노초~파남보 요소는 가시광선 파장의 차이라는 1차원 축으로 변별된다. 하지만 채도(S)와 명도(L)는 또 다른 차원의 변수라는 것이다.

컴퓨터의 그래픽 카드에서는 RGB 각 축에 대해 8비트의 정보량을 부여해서 총 2^24, 1600여 만 가지 색상을 제공하곤 하는데, 정작 1픽셀의 크기는 3바이트 24비트가 아니다. 컴퓨터가 처리하기 편한 단위인 4바이트 32비트 단위를 사용하며, 나머지 남는 8비트에다가는 픽셀의 알파 채널 정보를 넣곤 한다. 이건 여러 이미지를 부드럽게 합칠 때 활용된다.

알파 채널은 색깔을 나타내는 축 자체는 아니지만 색의 표현과 관계 있는 정보이다. 이걸 포함한 pixel format을 RGBA 구조라고 한다. 하지만 Windows의 GDI API는 1980년대에 개발되었으며, 픽셀에서 상위 8비트를 팔레트 등 독자적인 다른 용도로 이미 사용하다 보니 훗날 알파 채널을 제대로 지원하지 못하는 촌극이 벌어졌다. 그 역할은 GDI+ 등 후대의 API가 계승하게 됐다.

RGBA라는 개념은 물리학에서 XYZ 공간 세 축에다가 시간을 더한 XYZT 4차원과 뭔가 비슷하게 느껴진다.;; 그것도 기하학적 의미에서 정확한 4차원을 말하는 건 아니니 말이다. 하긴, 생각해 보니 3차원 컴퓨터그래픽에서는 픽셀마다 알파 채널이 아니라 Z buffer 값이 부가 정보로 들어가기도 한다.

3. 구 그리기

중고교 미술 시간에는 4B 연필 한 자루 들고 스케치북에다가 구를 그리는 데생(?) 실습을 해 보고.. 이과 나와서 컴공 전산을 전공한다면, 구 렌더링 정도는 C 코딩으로 저수준부터 뚝딱뚝딱 짜 봤으면 싶다.
둘이 매우 훌륭한 대조가 되리라 생각된다~! 후자의 경우, 구를 렌더링 하라고 openGL 셰이더 명령 한 줄 던져주고 끗~~이 아니라, 저 모든 픽셀의 RGB 값을 직접 계산해서 구하는 것을 말한다.

사용자 삽입 이미지

(본인이 직접 그리거나 생성한 그림이 아니니 오해하지 말 것! ㄲㄲㄲ)

이 픽셀이 구의 영역에 포함돼 있는지, 있다면 거리가 얼마나 되는지를 구의 방정식으로부터 구하고, 광원으로부터는 거리가 얼마나 되고 빛과 면이 접하는 각도가 어찌 되는지.. 최종적으로 밝기가 얼마가 돼야 하는지를 직접 공식 집어넣어서 계산으로 구한다는 뜻이다.

그림자까지 생각하면 일이 너무 어려워질지 모르니 필수가 아닌 옵션으로 남긴다만, 구 자체만이라도..;;
그럼 이 엄청난 계산을 실시간 애니메이션 수준으로 해내는 오늘날 PC와 폰의 그래픽 카드들이 얼마나 대단한 물건인지도 알 수 있을 것이다.

이런 이론 공부 잉여질 체험을 회사 취업한 뒤에 직장에서 할 수는 없을 것이고, 취업 목적 코딩 학원에서 할 수도 없을 것이다. 그러니 아직 학생일 때 학교에서 해야지...!!

4. AI

요즘 아시다시피 AI니 머신러닝이니 하는 분야가 아주 각광받고 있다. 현실에서의 문제의 목표와 input/output을 머신러닝 라이브러리가 이해하고 해결할 수 있는 형태로 변환하고, 데이터를 학습시키고 결과물을 얻는 건 확실히 학교에서 맛보기로나마 가르칠 필요가 있어 보인다.

자연어 처리라든가 영상에서 뭔가를 인식하기, ‘관련 추천 아이템 제시’ 같은 분야에서 요즘 AI들은 정말 눈부시게 똑똑해지고 기술이 발달해 있다.
개인적으로 좀 개발됐으면 하는 AI는 “문자열을 보고 폰트 종류 판별하기”, 그리고 “넓은 군중 사진을 보고는 여기에 사람이 몇 명이나 있나 추산하기”이다.

요즘은 AI를 통해 없는 정보를 유추해 내서 흑백 사진도 컬러로 얼추 복원하고, 흐릿한 영상을 선명하게 바꾸기도 한다. 그런 계산 능력이면 폰트 종류 유추는 말할 것도 없고, 이런 획이 요런 모양이었으니 다른 글자는 요런 모양이어야 하겠다는 것까지 유추를 못 할 이유가 없다. 그러면 한글이나 한자 같은 폰트를 만드는 일이 노가다가 줄어들고 한결 수월해질 것이다.

군중 사진에서 머릿수 카운트도.. 쉬울 것 같으면서도 은근히 어려울 수 있어 보인다. 하지만 기술적으로 불가능한 일은 절대 아닐 것이다. 이를 응용하면 사진에 찍힌 쌀알이나 콩알 개수를 세게 할 수도 있다.

지금 Google 검색은 영어는 정말 사람 말을 알아듣고 인간의 두뇌 활동을 어느 정도 흉내 내는 경지에 도달해 있다. 경악스럽게 그지없다. 유튜브 동영상에서 영어 자막을 자동 생성하는 걸 보면.. 어지간한 음성은 다 정확하게 알아듣는다.

여주인공이 격투를 벌이는 어느 첩보 영화의 제목을 까맣게 잊어버려서 “2017 female spy movie”라고만 쳤는데.. 우와, 저것만 토대로 Atomic Blonde라는 영화를 딱 정확하게 알아 맞히려면 도대체 저 영화의 특성을 어디까지 다 파악하고 있어야 되는 걸까..?
정말 외계인을 고문하는 기업이 아닐 수 없다.

꼭 인텔처럼 컴퓨터의 하드웨어 근간인 반도체의 본좌가 아니어도, 마소처럼 소프트웨어의 근간인 운영체제를 꽉 독점하고 있지 않아도 된다. 그 위에서 돌아가는 소프트웨어 내지 웹 서비스 중에서도 억 소리 나는 기술을 개발할 것들이 저렇게 넘쳐난다.;;

5. 암호 해독과 번역

난해한 수수께끼 암호를 풀기 위해 과거에는 언어학자가 동원되었다. 뭐, 보이니치 문서라든가 롱고롱고 문자, 로제타석처럼 인간이 만든 난해 정보를 해독할 때야 당연히 해당 지역의 고대 언어를 아는 것이 도움이 될 것이다.
하지만 현재의 군사 내지 보안 암호는 인간이 아닌 기계가 생성하다 보니 언어적인 요소가 전혀 동원되지 않으며, 오로지 수학자의 직관만이 필요하다. 2차 세계 대전 때 앨런 튜링이 독일군 에니그마 암호를 풀 때 딱히 독일어 지식이 쓰이지는 않은 것과 같은 이치이다.

기계번역도 이와 비슷한 맥락의 변화를 겪고 있다. 기계번역 시스템을 개발하는 데 입력 언어나 출력 언어의 전문가 내지 언어학자가 동원되지 않는다. 그냥 전산학자, 데이터 과학자, 머신 러닝 전문가가 동원된다.
취급하는 언어의 고유한 특성은 기계번역 시스템의 동작에 영향을 주지 않는다는 것이 한편으로는 굉장히 섬뜩한 점이다. 기계가 자연어든 암호문이든 언어 데이터를 취급하는 방식 자체가 근본적으로 바뀐 것이다.

6. 다중 상속

객체지향 패러다임에서 다중 상속이라는 걸 생각해 보자. 클래스가 기반 클래스를 하나만 두는 게 평범하고 일반적이고 권장되는 반면, 얘는 좀 특수한 상황에서 "논란과 무리수를 감수하고라도 둘 이상 갖는 것"이라는 특성이 있다.

이걸 인생에다가 투영해 보면 좀 뜬금없는 얘기지만 일부다처...;; 내지 복수 국적과 비슷한 것 같다.
C++에서 다중 상속을 지원해 봤는데.. 이건 좀 아니다 싶었는지 후대의 객체지향 언어들은 생짜 다중 상속은 금지하고, 데이터 멤버가 없는 인터페이스에 대해서만 복수 구현을 허용했다. class A extends B implements C,D,E처럼 말인데.. 이건 일부일처다첩-_-;;;처럼 들린다.

우리나라는 조선은 말할 것도 없고 일제 시대와 대한민국 초기에 이르기까지 오랫동안.. 일부다처체는 아니지만 첩이라는 게 관행적으로 있었다.
그러다가 1960년대, 박 정희 때 사회 구조를 대대적으로 뜯어고치면서 공무원들부터 첩을 두는 게 금지되었고(있으면 직장에서 징계=_=), 완전한 일부일처제가 자리잡았다.

이게 대놓고 불륜을 조장한다기보다는.. 전근대 시절엔 지금처럼 미혼 여성이 혼자 돈 벌고 사회 생활을 하는 게 도저히 가능하거나 용납되지 않았기 때문이다. 서로 필요하기 때문에 작은 마누라라는 게 존재했었다.

이런 결혼 말고 복수 국적도.. 나라마다 허용되는 정도가 케바케이고 우리나라는 징병제 병역 때문에 더 민감한 측면이 있다. 자기 원래 국적을 유지한 채로 외국의 영주권을 취득할 수는 있지만 완전히 시민권, 국적을 취득하는 건 또 별개의 문제가 된다.
우리나라의 경우, 이 대한민국 땅에 있을 때만은 한국 국적만 행사해야 한다는 각서를 쓴 뒤에 외국인의 복수 국적 취득을 허용한다.

국적 말고 이중학적, 이중인격 이런 건 명백하게 비정상일 것이다. =_=;;

Posted by 사무엘

2022/04/18 08:33 2022/04/18 08:33
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2010

Windows 운영체제에서 제공하는 GUI용 컨트롤 중에는 애니메이션 컨트롤이라는 게 있다. 이것은 명령 버튼이나 에디트 컨트롤, 리스트 및 콤보 박스처럼 Windows 1.x 시절부터 있었던 완전 native가 아니고, 1990년대 중반에 운영체제가 32비트로 갈아 타던 95/NT 3.5 시기에 도입된 '공용 컨트롤'에 속한다. 즉, 도구모음줄, 리스트뷰 컨트롤, 트리 컨트롤, 진행 상황(progress) 표시 컨트롤, 슬라이더와 같은 급이다.

애니메이션 컨트롤은 컴퓨터가 무슨 작업을 하고 있을 때, 작업 중임을 간단한 '움짤'을 통해 사용자에게 시각적으로 피드백을 주는 역할을 한다. 즉, progress 컨트롤과 같이 쓰이는 경우가 많으며, 그 작업의 소요 시간이 굉장히 길거나 언제 끝날지 예측할 수 없는 상황일 때 애니메이션이 더욱 유용해진다.

게다가 애니메이션은 단순한 눈요기 이상으로 컴퓨터가 지금 내부적으로 하는 작업이 무슨 의미를 지니는지를 사용자에게 상징적으로 일깨워 주는 효과도 있다!

사용자 삽입 이미지

  • 탐색기에서 파일을 복사 중일 때 종이가 이쪽 서류가방에서 저쪽 서류가방으로 날아가는 모습
  • 삭제 중일 때 종이가 날아가면서 인수분해-_-되는 모습
  • 다운로드 중일 때 지구본에서 사용자의 컴퓨터로 종이가 날아가는 모
  • 디스크 조각 모음을 실행할 때, 흩어졌던 건물 블록들이 짠~ 다시 한데 조립되는 모습

등이 좋은 예이다.
Windows 8 이후로 등장한 그 뱅글뱅글 돌아가는 동그라미들, 슉~ 중앙에 나타났다가 다시 슉~ 사라지는 동그라미들도 당연히 애니메이션에 속한다. 단, 얘들은 내부 작업의 의미를 시각화하는 건 없고 그냥 기하학적인 눈요기가 전부라 하겠다.

그럼 이 애니메이션 컨트롤은 어떤 형식의 파일을 사용할까?
컴퓨터 GUI에는 복잡한 코덱으로 디코딩해야 하는 전문적인 멀티미디어 동영상 말고, 그보다 가벼운 '움짤' 애니메이션 데이터라는 카테고리가 존재한다. 자동차에다 비유하면 버스보다 작은 승합차 정도에 대응할 것 같다.

  • 전문 동영상에 비해 파일 구조가 훨씬 더 단순하고, 프레임 크기는 작은 편이다.
  • 16/256색 같은 저색상도 지원한다. 저색상은 각 프레임을 무손실 압축으로 저장한다.
  • 오디오는 지원하지 않는다. 그 대신 투명색· 알파 채널을 지원한다. 영화 같은 전문 동영상에서는 이런 개념이 반대로 전혀 필요하지 않을 것이다.

카카오톡 이모티콘의 애니메이션이라든가 심지어 마우스 포인터의 애니메이션도 딱 이런 범주에 든다.
한때는 이런 움짤 저장용으로는 플래시(swf) 아니면 애니메이션 GIF가 널리 쓰였다. 그러나 플래시는 기능이 너무 많이 추가되면서 플레이어 런타임도 너무 무거워졌고.. 또 결정적으로 2010년대 중반부터는 완전히 퇴출됐다. gif야 뭐.. 256색의 한계를 벗어나지 못한 구닥다리일 뿐이고..

1990년대엔 오토데스크 사에서 개발한 flc/ fli라는 파일 포맷도 전문 동영상이라기보다는 애니메이션에 가까운 물건이었다. 심지어 Windows 매체 재생기의 초창기 버전이 재생을 지원하기도 했었다. 하지만 얘 역시 개인적으로는 실제 파일을 본 적이 전혀에 가까이 없으며, 소리소문 없이 듣보잡으로 전락하며 묻혔다.;;

Windows에서는 *.ani라고 애니메이션이 들어간 마우스 포인터 파일도 지원하긴 했지만.. 얘는 일반적인 비트맵이 아니라 아이콘에 대한 애니메이션이다 보니 담을 수 있는 그림에 대한 제약이 크다.
그러니 아주 오랜 세월이 지난 2010년대가 돼서야 png에다가 애니메이션이 추가된 apng, 그리고 jpg의 대체제로 개발된 webp에다가도 애니메이션이 추가된 Animated WebP가 뒤늦게 각광받는 중이다.

하지만 Windows 애니메이션 공용 컨트롤은 처음 도입되었던 1990년대 중반 이후로 시간이 완전히 정지한 채 시대에 너무 뒤쳐져 있다. 저런 최신 기술들을 전혀 지원하지 않고 오로지 avi만 지원하는데.. 제~~~일 단순하고 원시적인 run-length (RLE) 방식으로 압축된 256색 이하의 색상 영상만을 받아들인다.

얘의 디코딩 난이도를 이미지 파일 포맷에다 비유하자면, GIF에도 못 미치고 지금은 역사 속으로 사라진 PCX급밖에 되지 않는다.
저색상 기반답게 color key 기반으로 투명색 처리도 지원하긴 하지만.. 그럴 거면 gif라도 좀 지원할 것이지 하는 아쉬움이 남는다.

애니메이션 컨트롤은 왜 이렇게 허접하게 설계된 걸까? 전문적인 동영상 재생을 목적으로 만들어진 게 아니며, 탐색기에 들어가는 자그마한 애니메이션을 재생할 정도로만 극도로 최소주의 최적화 정신에 입각하여 기능이 구현됐기 때문이다.

1994~95년이면 모자이크나 넷스케이프 같은 WWW 기반 그래픽 웹브라우저가 이제 막 만들어졌던 시절이고, 386~486에 램 겨우 4~8MB급 컴퓨터로는 JPG는커녕 GIF 디코더를 돌리는 것도 다소 부담스러웠었다. 또한 그림판조차 BMP와 PCX 이외의 파일 포맷은 읽고 쓰는 걸 지원하지 않았었는데 GIF를 운영체제의 공용 컨트롤이 지원할 거라고는 전혀 기대할 수 없을 것이다.

물론 그땐 그랬다 치지만 지금까지도 애니메이션 컨트롤이 너무 빈약한 것은 변명의 여지가 없다고 하겠다. 그래서 이제는 탐색기 같은 운영체제 셸조차 애니메이션 컨트롤을 사용하지 않고 있다. 공용 컨트롤이란 게 원래는 셸에서 쓰던 물건을 보편적인 컴포넌트로 확장한 것이었는데 이건 참 아이러니한 현상이 아닐 수 없다.

요즘이야 탐색기에서 파일을 복사할 때는 전송 속도 그래프가 종전의 애니메이션을 대신하고 있다. 하지만 저 그림에서 보듯, Vista인가 7까지만 해도, 뭔가 서류 갈은 게 복사본이 짠~ 생기는 걸 형상화한 애니메이션이 떴었다. 파일을 삭제할 때도 비슷한 컨셉의 애니메이션을 볼 수 있었다.

그런 것들은 딱 봐도 알겠지만 Windows 9x 시절 같은 16~256컬러 나부랭이의 단순한 애니메이션이 아니다. 그리고 그건 애니메이션 공용 컨트롤로 재생하는 게 아니라는 것이다.;;
파일 내용을 표시하는 제일 중요한 부분조차 Windows 7의 탐색기부터는 리스트뷰 컨트롤을 사용하지 않는 것처럼 말이다.

(단, Spy++로 확인해 보면, 트리 컨트롤은 여전히 사용하고 있음. 외형을 많이 마개조해서 말이다.
반대로 Visual Studio는 먼 옛날 6.0 시절부터 지금까지.. 프로젝트/리소스 view에서 트리 컨트롤을 사용한 적이 없었다. 단적인 예로 트리 구조에서 ctrl+클릭으로 multiple selection이 동작하는 건 공용 컨트롤에서 전혀 지원되지 않는 기능이다. 흥미로운 사실이다.)

이상이다.
Windows 95 이후로 지금은 셸의 GUI와 공용 컨트롤 사이의 격차가 너무 많이 벌어져 있다.
9x 시절엔 작업 표시줄(taskbar)에 표시되는 각종 프로그램들 제목이 '탭 컨트롤'로 구현돼 있었다는 거 아는 분 계시려나.. 하지만 얼마 못 가.. 아무리 늦게 잡아도 XP때부터는 뭐 없이 당연히 자체 구현으로 바뀌었다.

Windows 10부터는 절대 안 바뀔 것 같은 메모장도 큰 파일의 로딩 속도가 획기적으로 개선됐고, \n 같은 줄 바꿈 문자 처리도 개선됐다.
에디트 컨트롤 같은 그 극도의 고인물 썩은물 코드도 마소에서 마음만 먹으면 개선될 수 있다. 그런 것처럼 시대 추세의 변화에 따라 애니메이션 컨트롤도 좀 개선이 됐으면 좋겠다는 게 개인적인 생각이다.

애니메이션 컨트롤과 관련된 기술적인 여담을 몇 가지 늘어놓으며 글을 맺도록 하겠다.

(1) 비트맵, 아이콘 따위는 응용 프로그램에서 자주 쓰이는 물건이다 보니 RT_BITMAP, RT_GROUP_ICON 같은 번호 기반의 표준 리소스 포맷도 있다. 그러나 애니메이션은 쓰이는 빈도가 압도적으로 낮다 보니 표준 리소스 포맷 번호가 제정돼 있지 않고, 그냥 "AVI"라는 포맷 문자열만 제정돼 있다. 거의 폰트(RT_FONT) 급으로 마이너하지 싶은데 말이다.

(2) 애니메이션 컨트롤은 전통적으로 백그라운드 스레드를 사용해서 애니메이션을 출력했는가 보다. 그리하지 않고 UI 스레드와 동일한 스레드에서 타이머만 사용해서 출력하게 하는 옵션은 ACS_TIMER라고 따로 있었는데..
Windows XP에서 도입된 공용 컨트롤 6에 들어간 애니메이션 컨트롤은 스레드 기능이 완전히 삭제되고 언제나 타이머 기반으로만 동작하게 됐다.

뭐, 애니메이션을 출력할 만한 상황이라면 작업은 어차피 백그라운드 스레드에서 진행되고 있을 것이고, UI 스레드는 당연히 살아 있어야 한다. UI 스레드가 응답 없이 block돼 있는데 애니메이션 컨트롤이 별도의 스레드로 혼자 살아서 UI 쪽에 접근하면.. 응답을 못 받고 같이 멎어 버리는 deadlock에 빠질 것이다.
애니메이션 컨트롤은 성능과 안정성 같은 요인을 감안해서 멀티스레드 기능을 빼 버린 것으로 보인다.

(3) progress 컨트롤은 공용 컨트롤 6 시절부터 marquee 애니메이션을 출력하는 기능이 추가됐다. 즉, 전체 작업량을 예측할 수 없어서 기약 없이 기다려야 할 때.. 프로그램이 작업 중이고 뻗지 않았다는 사실만 알려주는 뱅글뱅글 애니메이션 말이다.
요것만으로도 별도의 애니메이션 컨트롤을 사용해야 할 필요를 많이 줄여 주긴 했다. 완전히 대체해 버린 건 당연히 아니지만 말이다.

Posted by 사무엘

2022/04/04 08:35 2022/04/04 08:35
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2005

1. timestamp 기준, 그리고 달력 계산 문제

프로그래밍 언어 내지 운영체제 API에서 현재 시각과 관련된 정보를 얻는 함수는 다음과 같은 두 그룹으로 나뉜다.

  • 가변: 현재 프로그램이나 운영체제가 시작된 이래로 현재까지 경과한 시간을 밀리초나 그에 준하는 정밀한 단위로 되돌림. C언어의 clock() 함수, 또는 Windows API의 GetTickCount()가 이쪽에 속한다. 얘는 현재 날짜 시각을 얻는 용도가 아니라 그냥 짤막한 소요 시간 측정용이다.
  • 고정: 특정 고정 시점 이래로 현재까지 경과한 시간을 초 정도의 정밀도로 되돌림. C언어의 time() 함수가 대표적인 예이며 timestamp 저장용으로 쓰인다. 단, 고정 시점 기반이면서 정밀도도 초보다 더 높은 물건도 있다.
  • 날짜형: 애초에 출력 형식이 년-월-일-시-분-초가 따로 담긴 구조체이다. C언어에서는 time()의 결과값부터 구한 뒤에 gmtime이나 localtime을 호출해서 이렇게 변환해야 하지만, Windows API는 반대로 GetSystemTime/GetLocalTime을 이용해서 구조체부터 구한 뒤에 SystemTimeToFileTime을 호출하는 형태이다. 원론적으로는 C언어 방식의 순서가 더 자연스러울 것이다.

컴퓨터에서 특정 시각 timestamp를 저장하는 방식으로는 유닉스에서 유래된 "1970년 1월 1일 0시 이래로 경과한 초수"가 아주 널리 쓰인다.
하지만 그것 말고 NTP라고 네트워크 환경에서 통용되는 timestamp도 있는데, 얘는 10진법 계산의 편의를 염두에 둬서 그런지 1900년 1월 1일 0시가 기준이다. 두 timestamp는 70년이라는 격차가 존재하는 셈이다.

그런데 부호 있는 32비트 정수 자료형이 초 단위로 표현할 수 있는 기간, 즉 21억 5천만 초는 약 68년이어서 이 역시 공교롭게도 70년에 얼추 가깝다.
부호 있는 32비트 정수 기준으로 유닉스 timestamp는 2038년쯤에 overflow가 발생할 것으로 예상된다.
그 반면, 부호 없는 32비트 정수 기준으로 NTP는 2036년쯤에 overflow되어 숫자가 리셋될 예정이다.

본인은 직장에서 유닉스 timestamp를 네트워크 timestamp로 변환하는 함수를 구현할 일이 있었다.
기존 timestamp에다가 1900년 1월 1일부터 1970년 1월 1일까지의 초수라는 상수를 더해 주기만 하면 되니, 난 그 상수는 엑셀을 띄워서 간단히 구해서 썼다. 엑셀도 1900년 1월 1일이 기준이라는 걸 알고 있었기 때문이다.

그런데 이렇게 날수를 더해 줬더니, 계산 결과가 미묘하게 맞지 않고 하루 정도 오차가 났다.
그리고 그 원인은 alas... 엑셀은 1900년을 평년이 아닌 윤년으로 간주하고 하루를 더 집어넣었기 때문이었다.

현행 그레고리 태양력은 4의 배수인 해가 윤년이어서 2월이 29일까지 존재하게 되지만, 100의 배수인 해는 400의 배수인 해만 윤년으로 인정하고 나머지는 평년으로 간주한다.
하지만 이런 예외가 먼 197, 80년대의 스프레드 시트 프로그램에서는 구현하기가 너무 복잡했던 모양이다.

더구나 서기 1900년은 어차피 컴퓨터가 발명된 해 기준으로는 까마득한 옛날이어서 실용적인 의미가 없으니.. 윤년은 "그냥 4년 주기"라는 율리우스 달력 로직만 구현했던가 보다. 그리고 엑셀 역시 1900년 2월 29일이 존재할 수 있는 '버그'까지 똑같이 기존 프로그램(= Lotus 1-2-3 따위)과 호환성을 보장하기 위해.. 동일한 로직을 일부러 구현했다.

엑셀이 이렇게 윤년을 잘못 계산하는 건 1900년 하나뿐이니 걱정하지 않아도 된다. 미래의 서기 2100년이나 2200년은 평년으로 정확하게 계산하며, 2400년만을 윤년으로 계산한다.
이 동작이 영 껄끄러운지, 엑셀은 각 문서 파일에 대해 고급 옵션으로 "Use 1904 date system" 여부라는 걸 지정해 줄 수 있다. 논란의 여지가 있는 1900년이라는 걸 아예 삭제해 버리고 건너뛴 것 같은데.. 이러나 저러나 사용자에게는 큰 의미가 없고 널리 쓰이지는 않는 옵션으로 보인다.

어떤 경우건 엑셀에서 1899년 9월 18일 경인선 개통일을 날짜 타입으로 집어넣을 수는 없다. ㄲㄲㄲㄲㄲ 다른 날짜와 연계해서 연산을 할 수 없으며, 전화번호처럼 문자열로만 취급 가능할 뿐이다.

2. 핸들(포인터) 값을 대체하는 순서

GC가 없는 언어인 C++로 코딩을 하다 보면 각종 자원(메모리나 리소스, 객체)을 가리키는 포인터 및 핸들을 감싸는 wrapper 클래스를 만들 때가 많다.
그 클래스의 소멸자에는 if(_ptr) Free_Release_Close_Destroy(_ptr)처럼.. 핸들이 가리키는 자원을 해제하는 함수 호출이 들어가곤 한다. 그리고 객체 자체가 소멸되지는 않고 객체가 가리키는 핸들값만 바뀔 때도 기존 핸들에 대한 해제 작업이 자동으로 행해진다.

_ptr이라는 핸들 멤버를 갖고 있는 클래스에서 핸들값을 newVal로 변경하는 작업을 직관적으로 생각하면 다음과 같을 것이다. _ptr을 해제한 뒤 거기에다 바로 새 값을 대입하는 것이다.

if(_ptr && _ptr!=newVal) Free_Release_Close_Destroy(_ptr); //원래 핸들을 제거한 뒤
_ptr = newVal; //새걸로 대체

하지만 구조적으로 더 안전한 정석은 아래와 같이 임시 변수를 만들어서 두벌일을 좀 하는 것이다.

auto tmp = _ptr; _ptr = newVal; //새걸로 대체부터 한 뒤에
if(tmp && tmp!=newVal) Free_Release_Close_Destroy(tmp); //원래 핸들을 제거

핵심은 기존 핸들값을 다른 지역변수에다 옮긴 뒤, 자기 자신의 핸들을 먼저 새 값으로 바꿔 버리고, 지역변수에 대해서 해제 함수를 호출하는 것이다. 이거 무슨 swap 함수처럼 보이기도 하는데..
이렇게 해 주면.. 자기 자신이 해제되고 있는 중에 멀티스레드 등 모종의 이유로 인해서 해제 메소드가 또 호출됐을 때, 해제가 중복으로 행해지는 걸 막을 수 있다. 왜냐하면 자기의 핸들값은 대외적으로 이미 NULL 같은 딴 값으로 바뀌어 있기 때문이다.

실제로 C++의 스마트 포인터만 해도 unique_ptr::reset 같은 함수의 몸체를 보면 저렇게 임시 변수 대입, 멤버 변수 대입, 임시 변수에 대한 release 순으로 구현돼 있다.
분야가 좀 다르지만.. 전기 철도에서 팬터그래프는 안전을 위해 언제나 진행 방향 기준으로 최대한 뒤에 장착되는 것과 비슷한 이치로 보인다.

3. 이분 검색의 변종

모든 원소에 임의 접근이 가능한 배열의 경우, 원소들이 정렬돼 있다면 특성 원소를 찾을 때 '이분 검색'이 가능해서 O(n)이 아니라 O(log n)의 시간 복잡도로 작업을 수행할 수 있다. 비교를 한 번 할 때마다 후보군이 그거 하나만 없어지는 게 아니라 통째로 반토막이 나기 때문이다.
그런데 정렬된 배열에 대해서 원소 하나만 딱 정확하게 찾는 게 장땡이 아니고 다음과 같은 작업을 생각할 수 있다.

  • "1, 4, 8, 11" 같은 배열에서 5나 2, 10, 15 같은 새로운 원소를 삽입해 넣고 싶은데 어느 지점이 좋을까? (당연히 정렬된 상태 유지)
  • "1, 4, 8, 8, 8, 8, 11" 같은 배열에서 8이 정확하게 어느 오프셋부터 시작되어 어디에서 끝나는지 알고 싶다.

이런 것은 이분 검색의 변종이며, 이 역시 당연히 log n 시간 복잡도로 수행 가능하다. 정확한 이분 검색이 방정식이라면 이런 건 뭔가 부등식에 대응하는 것 같다. 날개셋 한글 입력기의 내부 동작에서도 종종 쓰이는 기능이다.

개인적으로는 타 비교 함수의 결과를 저런 용도대로 보정· 변조하는 2차 비교 콜백 함수를 만들어서 C의 bsearch 함수만으로 저런 기능을 구현했던 적이 있었다.
즉, 원래 사용하는 1차 비교 함수가 원소값이 동등하다는 0을 리턴했더라도, 바로 앞의 원소에 대해서 또 1차 비교를 했는데 걔가 또 0이라면.. 이 원소값에 대한 비교는 여전히 -1을 되돌리도록 보정하는 식이다. (탐색 지점을 앞으로 더 옮기게..)

그랬는데 C++에서는 사정이 더 좋아져서 이런 기본적인 동작은 algorithm이라는 라이브러리에 lower_bound, upper_bound, equal_range라고 내가 딱 원하던 함수들이 도입됐다. 포인터처럼 임의 접근이 가능한 iterator가 있다면 저 함수에다 바로 집어넣어 줄 수 있다.
하긴, 정렬도 qsort 하나뿐만 아니라 특별히 안정성 있는 stable_sort도 있고, 정렬되어 있는 두 컨테이너를 병합하는 함수도 있고.. 이런 것들이 algorithm의 섬세한 면모인 것 같다.

그런데 문제는 배열이 아닌 binary tree 형태로 정렬된 상태가 유지되는 컨테이너이다. set과 map..
얘들을 다룰 때 사용되는 iterator는 원소들의 임의 접근이 가능하지 않으며, 반대로 tree 노드의 좌우 이동 같은 게 iterator와 연계되지도 않는다.

물론 multiset도 아닌 이런 컨테이너에 equal_range이야 전혀 의미가 없을 것이고 새 원소 삽입 지점 같은 걸 찾아야 할 필요도 없을 것이다. 하지만 "들어있는 문자열 중에서 B로 시작하는 제일 첫 명칭은?" 같은 검색을 할 필요는 있다.
그렇기 때문에 set과 map에는 lower_bound와 upper_bound가 범용적인 함수가 아니라 클래스의 자기네 전용 멤버 함수로 구현되어 있다. 역시 C++ 라이브러리가 이런 걸 빠뜨리지는 않았고, 배열과 set/map에 대해서 대동소이한 형태로 동일 취지의 기능을 구현했다는 걸 뒤늦게나마 경험할 수 있었다.

Posted by 사무엘

2022/03/29 08:35 2022/03/29 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/2003

우리는 컴퓨터라는 건 20세기 중후반에 “(1) 진공관 → (2) 트랜지스터  (3) IC 회로  (4) 그 이후 LSI/VLSI 집적회로”의 순으로 내부 부품이 고도화· 첨단화돼 왔다고 배웠다. 집적회로 안에 트랜지스터가 몇천, 몇만 개씩 들어있고 0의 개수가 뻥튀기됐다고 말이다.
이 덕분에 컴퓨터는 메모리도 기하급수적으로 증가하고 속도도 기하급수적으로 빨라지면서 시공간이 워프 됐다. 그러면서 정작 자기 자신의 크기는 놀라울 정도로 작아져서 드디어 개인용 컴퓨터(PC)라는 것까지 존재할 수 있게 됐다.

더 세부적인 역사를 살펴보자면, 컴퓨터는 아직 1세대 시절에 “(1) 전동식이던 것이 완전 전자식으로 변모, (2) 10진법 대신 순수 2진법 기반, (3) 튜링 완전, (4) 프로그램 내장형”이라는 큰 격변을 거쳤다. 이에 대해서는 본인은 수 년 전에 글을 쓴 적이 있다.
특히 (3)을 통해 컴퓨터는 동적 메모리 접근과 능동적인 로직 구현, 즉 프로그래밍이란 게 가능해졌다. 그리고 (4)를 통해 메모리에 코드와 데이터가 모두 적재되고 소프트웨어라는 것이 존재할 수 있게 됐다.

그 다음으로 후대의 전자식 개인용 컴퓨터의 역사를 논할 때 적용할 수 있는 잣대는 바로.. CPU가 한 번에 취급하는 정보량의 단위 크기이다. 이것도 8, 16, 32, 64비트라는 네 단계로 구분할 수 있는데, 각 단계별로 정말 유의미한 변화가 있었다.
이 내역을 살펴보면 다음과 같다. “라떼는 말이야 컴퓨터가.. 그땐 그랬지!” 소리가 절로 나올 것이다.

1. 8비트 (1980년대 초)

  • 기종간 파편화가 엄청 심했다.
  • 보통 모니터+본체, 또는 본체+키보드 일체형.
  • 아무것도 안 꽂고 켜면 롬 베이식이 들어있곤 했다.

8비트 컴은 화면 해상도가 너무 낮아서 한글 한자 표현이 난감했다. 한 화면 전체의 정보량이 겨우 64KB에 머물러 있었을 뿐만 아니라, 이 등급의 컴퓨터는 메모리로나 처리 속도로나 8*8 256자짜리 라틴 알파벳 외의 다른 문자를 취급하는 건 영 메롱이었다.
(일본이 1980년대에 다른 분야가 아니라 게임에서 온갖 창의적인 작품을 내놓으며 펄펄 날았던 이유 중 하나도.. 짐작 가능하다시피 업무용이 아니니 자국 문자 처리를 별로 신경 쓸 필요가 없는 분야이었기 때문일 것이다. ㅡ,.ㅡ;; )

그리고 이때는 C 컴파일러조차 사치품이었다. 제품 가격으로나, 구동 요구 조건으로나, 생성된 코드의 성능으로나..
그러니 본격적인 프로그래밍을 위해서는 어셈블리어가 필수였다. 물론 이 시절 컴퓨터의 어셈블리어는 요즘 컴퓨터의 어셈블리어보다는 훨~~씬 더 단순하긴 했다.

8비트는 임베디드가 아니라 사람이 직접 다루는 개인용 컴터의 최소 마지노 선이나 다름없다고 하겠다.
그나마 얘는 1바이트의 정보량을 오늘날처럼 1옥텟과 동일한 8비트로 고정했다는 의의가 있었다. 더 옛날 컴퓨터들은 1바이트의 크기가 이보다 더 작고 들쭉날쭉이기도 했다~!

2. 16비트 (1980년대 말)

  • 뭔가 현대적인 컴퓨터 외형이 이때 갖춰졌다. 바이오스와 운영체제가 더 분명하게 분리됐다.
  • 모니터, 본체, 키보드가 모두 분리됐다. 그리고 테이프나 롬팩 대신 디스켓, 하드디스크.
  • 재귀적인 디렉터리 구조가 존재하는 파일 시스템.
  • IBM 호환 PC, 교육용 PC 등등 표준화 규격도 정착

과거 MS-DOS 2.0이 바로 CP/M에서 비롯됐던 8비트 잔재를 16비트로 확장한 것에 가까웠다. COM 대신 EXE, 재귀적인 디렉터리 구조 같은 것 말이다.

8비트에서 16비트로 넘어가고부터 모니터에 찍히는 글자의 크기부터가 확 작아지고 화면이 큼직해졌다. 640*480급의 고(?)해상도에서 14~16픽셀 크기의 글꼴이 지원되기 시작했기 때문이다. 저해상도에서는 256색 이상 색깔을 더 많이 표현할 수 있게 됐고.. 물론 이를 실제로 구경하려면 그에 상응하는 비싼 그래픽 카드와 컬러 모니터도 필요했다.

3. 32비트 (1990년대 초중반)

주소 공간이 그럭저럭 꽤 넓어진 덕분에.. 이제야 현대적인 컴퓨터의 내부 구조를 좀 제대로 실현할 수 있게 됐다. 가상 메모리, 보호 모드, 선점형 멀티태스킹/멀티스레딩.. 그리고 80386은 가상 메모리 구현을 위한 메모리 주소 매핑을 CPU 차원에서 바로 지원하기 시작했다.
각종 메모리에서 지긋지긋한 64KB 제약이 없어지고, 이 제약을 우회하려는 온갖 지저분한 꼼수 기법들을 익힐 필요가 없어졌다. (메모리 모델, EMS, XMS 등등)

32비트는 아키텍처가 오랫동안 안정되어서 굉장히 장수한 시기이다. 80386 이후로 486, 펜티엄 시리즈 등의 여러 CPU들이 등장했지만 얘들은 전부 32비트였다.
80486부터 캐시 메모리가 첫 등장했으며, 부동소수점 보조 프로세서가 CPU에 내장되기 시작했지만, 이런 건 소프트웨어의 호환성에 영향을 주는 변화가 아니다. 286에서 동작하지 않는 386 32비트 전용 프로그램은 엄청 많지만, 486에서만 동작하고 386에서는 동작하지 않는 프로그램은..?? 거의 없다는 것이다.

이제 PC와 워크스테이션이라는 체급 구분이 서서히 없어졌다. 3D 그래픽 렌더링도 Windows나 mac에서 바로..

4. 64비트 (2000년대 중후반)

64비트는 그냥 4GB 제약이 없어진 32비트의 연장선에 가깝다. 이전의 32비트에서 컴퓨터의 근간이 다 완성된 거나 마찬가지이기 때문이다.
PC에서 64비트는 멀티코어 패러다임과 비슷한 시기에 등장하고 보편화됐다. (인텔 Core2 Duo CPU) 그래서 32비트 전용 멀티코어나 64비트 싱글코어 CPU는 거의 존재감 없다.

이제는 슈퍼컴퓨터 전용 아키텍처라는 것도 없어졌다.
그런데.. 메인프레임은 Cray도 아니고 x86도 아니고.. 몇 비트짜리에 무슨 아키텍처와 어떤 특성을 가진 컴퓨터인지?? 난 잘 모르겠다.

옛날에는 억대의 슈퍼컴퓨터나 64비트 CPU를 썼지만, 지금은 주머니에 넣고 다니는 스마트폰의 CPU조차 다 64비트이다. 작다고 해서 16비트/32비트 따위를 쓰지는 않음. 요즘은 경전철이라고 구닥다리 협궤를 쓰지는 않는 것과 비슷한 이치이다(철차륜).
이제 모바일은 모바일이지, 임베디드와는 영역이 많이 달라졌음을 뜻한다. 전광판이나 자판기 같은 것에 들어가는 8비트 임베디드 MCU는 철도에다 비유하면 탄광 안에다 부설한 미니 협궤에 대응할 것이다. 채굴한 광물을 실어 나르는 용도이지, 여객용이 아니다.

※ 여담

(1) 8비트 시절에 화면 해상도가 얼마나 낮았는지를 실감해 보자.. 터미널 콘솔 하나 얹기도 버거워 보이는 환경에서도 무려 GUI를 만든 용자가 있긴 했다. ㄷㄷㄷㄷ

사용자 삽입 이미지

사용자 삽입 이미지
사용자 삽입 이미지
COMMODORE 64에서 64란, CPU가 64비트...는 개뿔, 메모리가 64KB라는 뜻이었다. ㄷㄷㄷㄷㄷ

(2) 옛날에 펜티엄 CPU가 등장했을 때는 이게 64비트라고 말이 많았다. 하지만, 펜티엄이 64비트로 확장한 건 주메모리와 CPU 사이의 데이터 버스의 대역폭뿐이다. 명령 집합, 레지스터 같은 내부 구조와 실질적인 동작이 64비트 단위로 돌아가는 건 당연히 아니다. 반대로 옛날에 386 SX는 원가를 낮추기 위해 CPU만 32비트이고 데이터 버스는 16비트였다.

(3) Windows NT의 구버전은 DEC Alpha 같은 64비트 CPU를 지원했던 적이 있다. 하지만 운영체제 자체는 여전히 32비트 기준으로만 동작했기 때문에 64비트 성능을 제대로 발휘하지 못했다. 마치 동시대의 Windows 3.x가 386/486에서도 16비트 코드 기준으로 동작했던 것과 비슷하게 말이다. (일부 멀티태스킹 기능을 제공할 때만 386 CPU 기능을 사용)

Posted by 사무엘

2022/01/29 08:34 2022/01/29 08:34
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1980

« Previous : 1 : 2 : 3 : 4 : 5 : ... 10 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2023/03   »
      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 31  

Site Stats

Total hits:
2078326
Today:
393
Yesterday:
1062