컴퓨터 소프트웨어계에는 이미 작성되어 있는 프로그램을 실제로 돌려 보지 않고(샌드박스 가상 머신 안에서..) 형태만 들여다보고는 버퍼 오버런이나 메모리 누출 같은 잠재적 위험성 및 논리 결함을 어느 정도 찾아 주는 '정적 분석'이라는 기술이 존재한다. 그 프로그램이 기계어 바이너리 형태이건, 고급 언어 소스 코드이건 형태는 무엇이건 상관없다.

그런데 정적 분석 툴은 그 누가 만든 것이라도 원천적으로 이론적으로 근본적으로 100% 정확하게 작동하지는 못한다.
이에 대해서 "아니 소스 코드가 무슨 자유 의지를 지닌 생명체도 아닌데 그 뻔한 로직을 분석해서 결과를 사전 예측하는 게 그렇게 어려운가? 단순히 소모하는 메모리와 계산량만 많아서 어려운 거라면 컴퓨터의 성능빨로 극복 가능하지 않은가? AI 기술을 접목하면 되지 않는가?" 처럼 생각하기 쉽다.

하지만 그렇지 않다. 그 말은 저런 차원이 아니다.
그런 함수는 단순히 현실적으로 구현하기가 어려운 정도가 아니라 논리 차원에서 모순에 빠지며 존재 불가능하기 때문이다. "모든 창을 막는 방패와 모든 방패를 뚫는 창 세트"와 동급으로 존재 불가능하다~! 창이나 방패의 제조 기술과는 무관하게 말이다.

가장~~ 원초적인 정적 분석 프로그램을 생각해 보기로 한다.
분석할 대상인 프로그램 코드, 그리고 그 프로그램에다가 넘겨줄 입력 데이터.
이 둘을 인자로 받아서 이 프로그램의 시시콜콜한 무슨 메모리 문제 따위를 진단하는 게 아니라..
이 프로그램이 무한 루프에 빠지지 않고 실행이 종료되기는 할지를 정확하게 판단해 주는 bool DoesThisProgramReturn(func, argument) 라는 가상의 함수 프로그램을 생각해 보자.

argument는 현실의 프로그램으로 치자면 명령 인자뿐만 아니라 프로그램이 파일이나 네트워크 형태로 읽어들이는 방대한 입력 데이터까지 모두 포함하는 개념이다. "일괄 처리 형태가 아니라 입출력이 실시간으로 들어오는 프로그램은요?" 이건 이 시점에서 그리 중요한 문제가 아니니 논외로 한다.
func는 뭐.. C/C++로 치면 기계어 코드를 가리키는 함수 포인터 정도로 생각하면 이해하기 편하겠다.

당연한 말이지만 저 함수 자체는 절대로 무한 루프에 빠지지 않고 언제나 유한 시간 안에 답이 나오는 게 보장된다. 무한 루프에 빠지는 프로그램을 의뢰했더라도 말이다. 그러므로 DoesThisProgramReturn(DoesThisProgramReturn, xxx)는 xxx로 무엇을 넘겨주건 그 정의상 리턴값이 언제나 true가 된다.

그럼.. 저 가상의 함수는 어떤 식으로 동작할지를 생각해 보자.
func가 가리키는 코드를 읽으면서 while(true); 같은 패턴을 발견한다거나,
더 구체적으로는 예전에 한번 거쳤던 state와 동일한 state로 이미 지났던 지점을 또 지나는 게 감지되면.. 이 프로그램은 실행이 끝나지 않는다는 결론을 내릴 수 있을 것이다.

이거 만델브로트(망델브로) 집합을 그릴 때 주어진 복소수의 발산 여부를 판별하는 것과 비슷하게 느껴진다.
배배 꼬인 복잡한 프로그램에서는 좀 어렵겠지만 그래도 도저히 불가능한 문제는 아니어 보이는데..??

하지만 튜링 기계는 우리가 흔히 생각하는 것보다 자유도가 더 높은 계산 모델이다.
메모리에 저장된 주소값에 해당하는 다른 메모리의 값을 마음대로 읽고 쓸 수 있을 뿐만 아니라(= 포인터) 거기 저장된 데이터를 코드로 간주해서 실행할 수도 있다(= 함수 포인터).

재귀 호출도 되고.. 또 앞서 살펴보았듯이 DoesThisProgramReturn 자신조차도 튜링 기계에서 실행되는 함수이기 때문에 DoesThisProgramReturn의 인자로 전달할 수 있다. 그리고 분석 대상인 타 함수가 얘를 또 호출할 수도 있다.
이런 상황까지 다 허용 가능해야 한다면 DoesThisProgramReturn의 존재 가능성은 굉장히 난감해진다.

아래와 같이.. DoesThisProgramReturn가 true라고 판정한(= 실행이 끝난다) func에 대해서는 "반대로" 자신이 무한 루프로 가 버리고, 실행이 끝나지 않는 함수에 대해서는 실행을 끝내는 HangIfReturns이라는 함수를 정의해 보자.

bool HangIfReturns(func) {
    if (DoesThisProgramReturn(func, func)) while(true);
    return true;
}

그러니 HangIfReturns(DoesThisProgramReturn)을 하면.. 얘는 무한 루프에 빠지게 된다.
DoesThisProgramReturn은 자기 자신에 대해서는 앞서 정의한 바와 같이 언제나 true를 되돌리고(= 늘 깔끔하게 실행 종료) if문을 만족하기 때문이다. 여기까지는 쉽다.

하지만 반대로 HangIfReturns가 DoesThisProgramReturn의 인자로 들어가면 어떤 일이 벌어질까? DoesThisProgramReturn(HangIfReturns, HangIfReturns)는 리턴값이 무엇이 되는 게 이치에 맞을까? 이제 좀 머리가 복잡해질 것이다.

DoesThisProgramReturn(HangIfReturns, HangIfReturns)가 true라면.. HangIfReturns 안의 if문은 true가 되므로 HangIfReturns은 무한 루프에 빠진다. 그러면 저 함수의 리턴값은 원래 false가 되어야 하게 된다.
반대로 저 리턴값이 false라면.. 역시 이제 HangIfReturns는 실행이 깔끔하게 종료되므로 저 함수의 리턴값을 정면으로 부정하는 결과가 나온다.

요컨대 HangIfReturns가 무한 루프에 빠지는지의 여부는 DoesThisProgramReturn의 리턴값에 따라 달라지는데, 이 과정에서 서로 물고 무는 구조적인 모순이 발생하는 셈이다.
이 모순은 DoesThisProgramReturn라는 함수가 존재한다는 가정으로부터 비롯되었다. 그러니 튜링 기계 하에서 다른 코드의 실행 종료 여부를 완벽하게 판단하는 코드를 똑같은 튜링 기계 기반으로 구현하는 것은 불가능하다는 것이 입증된다.

이 논리는 "정지 문제"(halting problem)이라고 불리며, 컴퓨터라는 기계의 계산 가능 범위를 고민하게 하는 매우 탁월한 통찰이다. 이걸 처음으로 생각해서 논문으로 발표한 사람이 바로 그 이름도 유명한 앨런 튜링이다.

과학 철학에서 "반증 가능한가", 천문학에서 "관측 가능한가"처럼.. 전산학에서는 "계산 가능한가, 튜링 기계를 돌려서 답을 구할 수 있는 문제인가"가 중요한 고민거리가 된다. 계산 자체가 이론적으로 가능해야 그 다음 관심사는 "실용적으로 유의미한 시간 만에 빨리 해결할 수 있는가?", 더 구체적으로는 "입력 크기 N에 관한 다항식 급의 시간 안에 해결 가능한가 (팩토리얼이나 지수 함수 급이 아니라)"라는 시간 복잡도가 될 것이다.

TSP(순회하는 세일즈맨) 문제 같은 NP-완전 문제는 이론적으로 알려진 시간 복잡도가 너무 높기 때문에 실생활에서는 적당히 성능이 좋은 다항 시간 근사 알고리즘이 쓰인다.
그래도 정지 문제는 3-SAT 문제라든가 NP-완전처럼 시간 복잡도를 따지는 증명보다는 덜 난해하고 직관적인 설명도 가능하기 때문에 수식 없이 블로그에다 증명 방식을 소개도 할 수 있다. 현실에서는 논리적으로 100% 완벽하고 헛점이 없고 100% 정확하게 동작하지는 못하지만 그래도 현실적으로 충분히 정확하고 속도도 적절한 각종 소스 코드 정적 분석 기능이 개발되어 쓰이고 있다.

Posted by 사무엘

2021/05/24 19:36 2021/05/24 19:36
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1891

1. 압축 유틸

요즘은 Adobe Reader 같은 거 설치할 필요 없이 크롬이나 Edge 같은 브라우저만으로도 자체적으로 pdf 문서를 바로 열어 볼 수 있다.
압축 유틸리티에서 광학 디스크 이미지 파일의 내용을 바로 볼 수 있게 된 것과 비슷해 보인다. 한 분야의 프로그램이 비슷한 다른 분야의 프로그램의 역할을 일부 흡수해 버렸다.

물론 이미지 파일을 새로운 드라이브로 mount 시키는 것까지 압축 유틸이 지원하지는 않는다. 그것까지 지원하면 압축 유틸의 기능이 옛날 도스 시절의 Double Space 같은 디스크 압축 유틸 급으로 커지는데.. 요즘은 그런 기능이 필요할 정도로 디스크의 용량이 부족한 시절이 아니기 때문에 유행이 지났다. 그리고 결정적으로 드라이브 mount는 이제 운영체제(Windows 10)가 자체적으로 제공해 주는 기능으로 흡수되기도 했다;;

국내의 경우 20여 년 전, 이 바닥이 WinZip, WinRAR 같은 외국산 압축 유틸리티 일색이던 시절에 이스트소프트의 '알집'이 처음에 적절한 마케팅 덕분에 시장 선점을 잘 해서 폭발적인 인기를 누렸다. 그러나 버그· 안정성 문제에 적절히 대처하지 못해서 2000년대 말쯤에 컴덕들 사이에 욕을 엄청 먹었으며, 그 와중에 기업 대상 유료화까지 선언하는 바람에 입지를 더욱 잃게 됐다.

그 와중에 개인 개발자 1인의 작품인 '빵집'이 알집의 대체제로 각광 받아서 2000년대 후반에 큰 인기를 끌었다.. 하지만 빵집은 개발자의 개인 취미 생활이다 보니 유지보수에 한계가 있었고, 결국 개발이 중단되어 역사 속으로 사라졌다.
그리고 오늘날이야.. 그 틈새를 저격한 반디소프트의 '반디집'이 탁월한 완성도로 천하를 평정했다.

압축 유틸의 역사를 읽어 보노라면, 소프트웨어는 모름지기 수요와 타이밍, 시장 공략을 잘 해야겠다는 걸 느낀다.
zip은 압축 해제뿐만 아니라 생성까지 소스가 완전히 공개돼 있고 그 다음부터 7z, ace, rar 등 압축 알고리즘들의 압축률은 이론적인 정보량 한계에 근접해서 거기서 거기이다 보니.. 알고리즘은 zip 하나만 있으면 되고 그 뒤 멀티코어, 64비트, 유니코드, 기본적인 보안, 운영체제 셸과 잘 연계하는 UI...

이것만 제공되면 그 다음부터 굳이 유료 유틸을 쓸 필요가 크게 줄어드는 것 같다. 실제로 본인도 '-집' 계열 유틸을 사용하기 시작한 뒤부터는 Windows에서 zip 말고 rar 등 다른 압축 파일을 '생성'해 본 적이라고는 전혀 없는 것 같다.

2. 유튜브

(1) 유튜브 동영상에 광고가 5~10여 년 전에 비해 굉장히 많이 늘어난 게 느껴진다.
뭐, 쟤들도 흙 파서 먹고 사는 건 아닐 테니, 오랫동안 무료로 잔뜩 뿌리고 투자했던 것을 회수할 때가 됐다. 전세계에서 발생하는 천문학적인 수의 동영상들을 저장하고 전송 트래픽을 감당할.. 서버 유지비가 장난 아니게 깨질 것이며.. 몸값 비싼 엔지니어들을 고용하는 인건비도 상상을 초월할 것이다. 서버 관리자, 웹 UI 디자이너 및 개발자, 동영상 코덱 전문가, 동영상 컨텐츠들의 검색과 분류 알고리즘 전문가 등..

그러니 동영상 포털이 사용자에게 거부감을 제일 덜 주면서 수익을 내는 건 광고 또는 사용자에게 "광고 안 뜨는 기간제 유료 계정" 판매로 자연스럽게 귀착될 것이다. 나도 광고가 너무 잦아지니 잠시 동안만이라도 광고 없는 유튜브 프리미엄 유료 계정을 써 보고 싶다는 생각이 종종 든다. 유튜브도 사용자를 이렇게 적당히만 귀찮게 하는 걸 목표로 하지 싶다.

요즘 친구들끼리 생일 선물로 카카오톡으로 이모티콘이라든가 커피 상품권을 주고 받는 게 있다. 그런 것처럼 몇천 내지 1~2만원대의 유튜브 프리미엄 n개월 이용권이 온라인/모바일 생일 선물로 오가는 건 어떨까 싶다.

여담이지만, 유튜브뿐만 아니라 평소에 위키백과를 지식 습득용으로 유용하게 사용해 온 사람이라면 거기에도 후원금을 소액이나마 내는 게 좋을 것이다. 특정 기업의 입맛에 휘둘리지 않고 상업 광고도 없는 개방된 지식 저장소는 컴퓨터와 인터넷을 지금 같이 누구에게나 평등하고 투명하게 개방된 정보의 바다로 만드는 데 절대적인 기여를 했기 때문이다.

(2) 다음으로, 돈이나 광고와 별개로 본인이 요 근래에 유튜브에 대해서 느끼는 굉장히 큰 불만이 하나 있다.
HD급 이상의 무거운 고화질 동영상일수록 더 두드러지는 것 같은데.. 슬라이더에서 좌우 화살표를 눌러서 앞뒤 5초 남짓 단위로 seek를 한번 하는 데 걸리는 딜레이가 너무 길다는 것이다. 동일 화질 기준으로 그냥 하드에 저장된 동영상을 데스크톱용 플레이어 앱에서 seek하는 것만치 빨리 즉시는 절대 못 한다. 답답하지 않으신가?

옛날 저화질 동영상은 이렇지 않다. 이건 다운로드 자체는 이미 다 된 구간을 돌아다니는 것만 말한다. 그러니 네트워크 상태하고도 무관하다.
기술적인 한계 때문에 느린 건지 아니면 이것도 설마 현질 유도를 위해 고의로 들어간 핸디캡인지는 잘 모르겠다.

(3) 끝으로, 유튜브 유료 계정에 제공되는 서비스로는 광고 제거뿐만 아니라 동영상을 아예 로컬에다 다운로드하는 것도 있었다.
하지만 그건 별도의 서비스가 없더라도 뒷구멍을 통한 다운로드 서비스가 넘쳐나다 보니 유튜브에서도 단속을 포기한 것 같다. 별도의 앱이던 게 더 간편한 웹으로 바뀌기까지 하고 말이다. 사실 이건 기술적으로, 근본적으로 막을 수 있어 보이지는 않는다.

3. 이메일: 대용량 파일 첨부, 발송 확인 및 취소 기능

15년쯤 전에 구글 gmail이 최초로 1GB짜리 웹 기반 무료 이메일을 개설한 이래로 요즘은 어디건 이메일 서비스는 기본이고 용량이 기가바이트급이다. 하지만 이메일은 편지함 용량과 컴퓨터의 하드 용량이 증가한 것에 ‘비하면’, 무슨 영화 파일 급의 대용량 첨부 파일을 주고 받기에는 여전히 좀 버거운 수단이다. 기껏해야 수~수십 MB 정도가 한계?

초대용량 파일은 메일에다가 직접 붙이는 게 아니라 다른 클라우드/웹하드에다 올리고 나서 그거 링크만 메일에다 넣는 형태로 대체되는 게 요즘 추세이다.
수신 확인 및 오발신 취소 같은 것도 이메일의 정식 프로토콜/스펙에 규정된 기능이 아니라 각 웹메일 서비스 사이트에서 자기 계정간 이메일에 한해서만 제공되는 비표준 편의 기능인데.. 이것도 좀 표준으로 승격됐으면 하는 바람이 있다.

4. 크롬 브라우저로 네이버 블로그 첨부 파일 다운로드

크롬 브라우저로는 네이버 블로그 기반의 사이트에서 첨부 파일 다운로드가 잘 되지 않는 문제가 있다.
나만 겪는 현상인 줄 알았는데 아니었구나..

검색을 해 보니, 네이버 블로그는 https 기반인데 다운로드 링크는 보안이 취약한 http 기반이어서 크롬이 의심스럽다는 이유로 다운로드를 차단한 것이었다.
즉, 네트워크 구조에 문제가 있어서이지, 첨부 파일의 내용에 문제가 있어서가 아니었다.

이렇게 웹페이지의 구성요소에 https와 http가 뒤섞여 있으면 브라우저가 의심스럽고 불안하다고, 그래도 내용을 다 보고 싶냐고 온갖 귀찮은 확인 메시지를 사용자에게 띄운다. 다들 한 번쯤은 그 모습을 본 적이 있을 것이다.

그런데 크롬의 경우, 그 어떤 에러 메시지도 없이 그냥 일방적으로 네이버 블로그로부터의 다운로드를 씹어 버리니 당혹스러웠다. 은행 ActiveX도 아니고 파일 다운로드를 위해서 구닥다리 IE를 끄집어내는 촌극이 벌어지기도 했다.
뭐, 궁극적으로는 천하의 네이버가 이 문제를 해결하고 네트워크 구조를 불안 요소가 없게 어서 고쳤으면 좋겠다.

크롬은 이제 올해부터 플래시조차 지원을 완전히 끊었다. 아직도 메뉴가 플래시 기반인 웹사이트는 한 몇 년은 관리를 안 한 완전 구닥다리.. "1024*768 해상도에서 IE 6 브라우저에서 가장 잘 보입니다" 이러면서 제로보드 게시판까지 같이 붙어 있는 사이트일 가능성이 높을 것이다.
세월이 참 많이도 흘렀다. 플래시, 제로보드, Visual Basic 6, 재래식 hlp.. 이런 것들이 역사 속으로 사라졌다.

5. 마이너한 검색들

일반적으로 널리 쓰이는 기능은 아닐 테니 유료 서비스 형태로 제공되더라도..

(1) 많고 많은 웹툰들은 그림 파일뿐만 아니라 말풍선 안의 대사들도 색인화돼서 대사로 해당 컷의 검색이 됐으면 좋겠다.
짤방으로 써먹고 싶은데 그 그림이 긴 웹툰 시리즈의 어느 화에 있었는지 기억을 못 할 때가 많다.
물론 "이 학교의 주인은 이사장인 나예요."(사립정글고), "네놈을 살려 두긴 쌀이 아까워!"(이말년), "선 넘네"(엉덩국 애기공룡 둘리) 같은 거야 너무 강렬하고 유명하니 일반 검색 엔진으로도 대사와 컷 이미지가 개념적으로 연결돼 버렸지만.. 그렇지 않은 컷도 많다.

(2) 주선율 음표 표기로 음악 검색. 밖에서 재생되는 음원을 들려줘서 비슷한 음반의 노래를 찾는 건 이미 서비스 되는 게 있지만.. 그건 음원이 없고 사람의 오랜 기억 속에만 존재하는 음악을 찾아 주지는 못한다. 내가 말하는 건 음악들의 주선율 악보를 색인화해서 검색하는 것이다. 다만, 이걸로 검색하려면 사용자도 최소한의 채보· 기보 능력이 있어야 한다.

검색 엔진이란 게 처음에는 같은 웹에서 텍스트 위주로만 검색을 지원했다. 그러나 요즘은 웹뿐만 아니라 종이책, 잡지, 옛 신문들과 방송 자료, 논문 같은 오프라인 매체로 범위가 확장되었으며, 정보의 형태도 텍스트에 국한되지 않고 그림과 동영상까지 취급한다.

그러니 이게 앞으로는 텍스트뿐만 아니라 사람이 마우스로 얼추 끄적인 스케치와 비슷하게 생긴 그림이나 실제 로고타입을 찾아 주고, 콩나물 배열만으로 음악을 찾아 주는 경지에 도달하지 않을까 싶다. 그야말로 사람의 기억을 보조해 주는 도구가 되는 것이다. 그리고 국내 웹툰뿐만 아니라 과거의 뉴스 보도, 특히 대한뉴스들도 다 색인화되면 엄청난 도움이 될 것이다.

Posted by 사무엘

2021/04/16 08:33 2021/04/16 08:33
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1877

0. 들어가는 말

세상에는 누구나 드나들 수 있는 공공장소와 누구나 신호를 주고받을 수 있는 통신망이 있지만, 사람마다 사생활도 있고 비밀도 있다. 이런 게 보장되지 않으면 인간이 정상적으로 살아갈 수 없으며, 사실은 생존에 필요한 기본 욕구를 충족시킬 수도 없어진다.
그렇기 때문에 어떤 장소나 어떤 정보는 내부의 믿을 수 있는 사람, 우리 조직 소속인 사람만 접근할 수 있게 해야 한다.

이를 구현하기 위해 전자에 대해서는 열쇠와 자물쇠라는 게 만들어져 왔고, 후자를 위해서는 암호 기술이라는 게 개발되었다. 열쇠가 없는 사람, 암호를 모르는 사람은 문을 열고 들어갈 수 없고 그 자료를 열람할 수 없다. 심지어 정보가 담긴 매체라든가 물건이 담긴 금고 자체가 유출되더라도 그 안의 물건에 손댈 수는 없다.

열쇠와 암호는 서로 담당하는 영역이 다르지만 심상이 아주 비슷한 구석도 있다. 요즘은 자물쇠도 열쇠 대신 일종의 숫자 암호인 디지털 도어락으로 바뀌고 있고, 암호학에서도 key라는 용어가 즐겨 쓰이니 말이다.

다만, password라는 개념의 '암호'와, 원본 정보를 password 없이는 알아볼 수 없게 변조하는 '암호화'(cryptography, encryption), 그리고 암호화가 적용된 텍스트를 작성하는 것 내지 그 결과물인 암호문(cipher).. 이게 우리말에서는 딱 부러지게 잘 구분되지는 않는다는 점을 감안할 필요가 있다. 마치 '뛰다'(jump/run), '다른'(other/different), '푸르다'(green/blue) 이런 게 잘 구분되지 않는 것처럼 말이다.

보이니치 괴문서처럼 암호 사용 여부와는 무관하게 단순히 체계와 의미가 파악되지 못한 물건도 decipher되지 못했다고 말한다.
그에 비해 한국어 ‘해독’은 동음이의어 한자의 특성 때문에 ‘독’에 read라는 뜻뿐만 아니라 poison이라는 뜻까지 있어서.. 미묘하게 중의적인 심상을 자아낸다. 마치 ‘충전’의 중의적인 심상처럼 말이다. (전기도 충전, 금액도 충전..)

1. 패스워드의 관리, 해시 함수

먼저, 암호화와 무관하게 로그인 패스워드 자체에 대한 보안을 논하는 기본 원칙이 있다. 이 주제에 대해서는 본인이 마지막으로 글을 썼던 때가 무려 7년 전이었구나.;; (☞ 이전 글)
사용자의 입장에서는 “다양한 종류의 문자를 섞어서 최소한 10자 이상의 긴 문자열로 정할 것, 주기적으로 바꿔 줄 것” 이런 게 있다.

물론 누군가의 원한을 사고 있어서 작정하고 당신의 계정을 뚫으려 노력하는 공격자라도 있는 게 아니라면.. 이런 얘기에 지나치게 민감해할 필요는 없다. 암호 좀 허술하게 만든다고 해서 현실에서 당장 위험에 빠지는 건 아니다. 하지만 그렇다고 해서 1234, asdf, iloveyou, 생일, 전화번호 정도로 암호를 너무 성의없게 만드는 건 정말 피해야 한다.

그리고 사용자의 접속 정보를 저장하는 운영자의 입장에서는 암호를 절~대로 평문 그대로 저장하지 말아야 한다. 게다가 암호 문자열이 무슨 도스 시절 파일 이름마냥 10~15자 같은 제약이 걸려 있거나 특정 특수문자 기호를 지정하지 못한다면.. 그건 정말 기본적인 보안 관념도 없던 쌍팔년도 시절 사고방식의 미개한 사이트라고 욕 먹어야 할 것이다.

사용자가 암호를 잊어버렸다면 사이트 운영자라도 그 암호를 알 수 없는 게 정상이다. 본인 인증을 시행한 뒤에 임의로 지정한 새 암호를 알려줘야지, 기존 암호를 그대로 알려주는 사이트는 그 자체가 보안이 매우 허술하다고 실토하는 것과 같다.

그러니 이런 패스워드는 딱히 key 없는 단방향 암호화라는 변조를 거쳐서 저장해야 하는데, 이럴 때 해시 함수라는 게 쓰인다. hash란 어떤 임의의 길이의 원본 문자열이 주어졌을 때 원본과는 완전히 다르고 무질서하게 변조된 다른 고정된 길이의 문자열 내지 바이트 시퀀스를 되돌리는 수학 함수이다. 원본 문자열이 조금만 바뀌어도 완전히 확 달라진 결과값이 나와야 한다.

F(X) → Y인데, 역으로 Y로부터 X를 복원하는 것은 수학적으로 불가능하다. 그리고 F(A) ≠ F(B) 라면 절대적으로 A≠B이지만, F(A)=F(B)이면서 여전히 A≠B일 확률은 매우 매우 낮은 확률로 존재한다. 비유하자면, 퀵 정렬의 시간 복잡도를 n^2로 만드는 input을 우연히 만들 수 있을 정도의 확률로 존재한다.

패스워드의 비교는 사용자가 입력한 문자열을 hash한 결과와, 저장된 패스워드 hash값을 비교함으로써 행해진다. 평문을 비교하는 게 아니라는 것이다.
사실, 이런 해시 함수는 패스워드의 보관뿐만 아니라 방대한 파일이 정확하게 잘 전송되었는지 동등성을 검증하는 용도로도 즐겨 쓰인다. 수 GB짜리 파일의 해시값이 얼마가 나와야 정상인데 엉뚱한 값이 나왔다면 중간에 오류가 있었다는 뜻이 되기 때문이다.

해시 함수가 튼튼하고 안전하려면 (1) F(X)로부터 X를 역으로 추적하는 것이 불가능해야 하고, (2) 서로 다른 두 입력 A, B에 대해서 동일한 해시값이 산출되는.. 다시 말해 ‘충돌’ 사례가 없어야 한다. 전자는 암호화된 값으로부터 패스워드를 복원하는 것이고, 후자는 의도하지 않았던 엉뚱한 암호로 원래 패스워드의 사칭을 가능하게 하기 때문이다.

성능 좋은 해시 알고리즘으로는 MD5니, SHA-256 이런 부류가 공개되어 쓰이고 있다. 이들도 한번 만들고 끝이 아니라 버전과 출력 해시의 길이가 올라가는 편인데, 기를 쓰고 공격하려 애쓰는 연구자에 의해 충돌하는 입력값 쌍이 발견되기도 한다. 그러면 그게 해당 알고리즘을 사용하는 소프트웨어의 잠재적 보안 결함으로 이어진다.

그리고 해시값으로부터 원래 입력을 역추적하기 위해 요즘은 상상을 초월하는 물량 데이터빨이 동원된다. “MD5 해시값을 자동으로 계산해서 구해 드립니다”라는 웹페이지를 개설한 뒤, 전세계 사용자가 입력했던 문자열과 그 해시값 수십억 개를 몽땅 보관해 놓는 것이다. 그래서 산술 연산을 하는 게 아니라 DB를 조회함으로써 해시값 복원을 한다. 우리가 남들도 떠올릴 만한 평범한 문자열로 패스워드를 만들면 위험한 이유가 이 때문이다.

2. 대칭 키 암호화

이게 우리가 흔히 생각하는 데이터 암호화이다. 발신자가 A라는 텍스트를 K라는 패스워드(혹은 key)를 이용해서 E라는 암호화 함수로 암호화해서 B라는 암호문을 얻는다. 수식으로 표현하면 B=E(A, K) 정도? 그러면 수신자는 D라는 복호화 함수를 이용해서 D(B, K)를 돌림으로써 A를 얻는다.
이걸로 끝.. ‘대칭’이라는 말은 발신자와 수신자가 K라는 동일한, ‘대칭인’ key를 공유하는 암호 체계라는 뜻이다.

암호화 함수는 해시 함수와는 달리 복호화 함수도 존재하며, key만 안다면 원문 복원이 가능하다는 차이가 있다. 해시 함수는 애초에 어떤 입력에도 128비트 같은 동일한 길이, 즉 동일한 정보량을 가진 해시값이 돌아오지만, 암호화 함수는 출력의 정보량이 입력의 정보량과 대등하다. 그러니 용도가 서로 근본적으로 완전히 다르다.

컴퓨터가 없던 시절에도 마치 VMS로부터 WNT (Windows NT)라는 명칭을 만드는 것처럼 글자들을 일정 간격 앞뒤의 것으로 변조하거나, 심지어 key 문자열의 형태를 토대로 각 글자들을 가변적인(하지만 규칙과 패턴은 물론 있는) 오프셋만치 변조하는 기법 정도는 응당 쓰였다. 모든 글자를 고정적인 오프셋만치 변조하는 암호는 각 글자들의 빈도수 분석을 통해 비교적 금방 깰 수 있을 것이다.

2차 세계 대전까지만 하더라도 전자식 컴퓨터라는 게 사실상 없던 시절이었고, 지금에 비하면 매우 단순하고 원시적인 암호가 쓰였다. 연합군이 승리한 것에는 적국(일본, 독일) 군대의 암호를 풀어낸 것이 아주 큰 기여를 했음이 주지의 사실이다.
컴퓨터가 등장한 뒤부터는 매우 컴퓨터 친화적인 비트 회전과 XOR 연산이 암호화에 즐겨 쓰이고 있으며 그 수준이 과거엔 상상도 할 수 없을 정도로 복잡해졌다. 문자열을 암호화하기 위해서는 문자열을 구상하는 각 문자들을 숫자처럼 취급하는 게 필수이다.

정보 보호라는 업계에서 이런 암호화와 관련하여 통용되는 철칙이 있다. 암호화 알고리즘은 자신의 동작 방식과 로직이 소스 코드 차원에서 몽땅 공개되어 있더라도 절대적으로 안전해야 한다는 것이다. 데이터의 안전은 key가 보장해야지, 알고리즘을 공격자가 알고 있는지의 여부와는 무관해야 한다.
그렇기 때문에 이 바닥은 소스를 공개할 수 없는 우리만의 초특급 비밀 노하우 원천기술 같은 게 없다. 모든 게 투명하게 공개돼 있고 심지어 취약점이 발견된 것, 수정 내역도 공개된다. 이런 열린 관행 덕분에 컴퓨터 세계는 역설적으로 더 안전해질 수 있었다.

여담이지만, 지난 2009년엔 ‘코드소프트’라는 정체를 알 수 없는 어느 스타트업 기업에서 상금까지 걸면서 자기네 암호화 알고리즘에 대한 크랙 공모전을 주최했으나 비슷한 시기의 T-max 운영체제 같은 흑역사만 남겼던 적이 있다. 자기네 핵심 기술이라던 암호화 알고리즘은 허술하기 짝이 없어서 겨우 몇 시간 만에 뚫려서 큰 망신을 당했으며, 그 회사도 얼마 못 가 통째로 폐업했기 때문이다(소스는 비공개이고 임의의 데이터에 대한 암호화 결과 확인만 가능). 걔들은 암호화 알고리즘의 전문가는 고사하고 보안에 대한 기본 관념이 있긴 한 기업이었는지가 의문이 든다.

대칭 키 암호화 알고리즘으로는 AES, DES 같은 기성 표준 알고리즘이 있고 이것도 버전 내지 사용하는 정보량(비트수)이 올라가고 있다. AES는 오늘날의 컴퓨터 성능으로는 뚫리는 데 걸리는 시간이 위험할 정도로 짧아졌기 때문에 이제 사용이 권장되지 않는 지경이 되었다.
우리나라에서도 SEED, ARIA, LEA라는 알고리즘을 자체 개발해서 국가 표준으로 지정한 바 있다. 국정원 내지 한국 인터넷 진흥원 이런 데서 날고 기는 수학 박사를 채용해서 머리 굴려서 개발한 듯하다.

문서나 압축 파일에 암호를 거는 기능에도 응당 이런 암호화 알고리즘이 쓰인다.파일 내부에다가 패스워드를 평문으로 저장하는 미친 짓을 하지는 말아야 할 것이다. 혹은 파일 내용 자체를 암호화하지 않아서 헤더의 패스워드 부분만 건너뛰고 나면 나머지 내용을 고스란히 읽을 수 있게 하는 것도 치명적으로 잘못된 설계이다.
틀린 패스워드를 주면 해독이 잘못되어 완전히 엉뚱한 파일이 생성될 텐데, 패스워드가 맞는지 틀린지를 확인하는 건 정상적으로 해독됐을 때의 파일 checksum hash 같은 걸 별도로 둬서 확인해야 한다. 암호화 알고리즘 다음에 붙는 CBC, GCM 같은 모드 명칭은 바로 이런 검증 방식을 가리킨다.

안전한 암호화 알고리즘이라면 평문이나 key가 조금만 달라져도 이들의 원래 형태와 통계적 특성을 전혀 알 수 없는 엉뚱한 암호화 결과가 출력으로 나와야(혼돈과 확산) 안전할 것이다. 이 점에서는 해시와 비슷한 구석이 존재하며 심지어 난수 생성 알고리즘과도 비슷하다고 볼 수 있다. 입력을 0, 1, 2 .. 순차적으로 주고 이를 hash시킨 결과가 난수나 마찬가지이고 암호화도 이와 크게 다르지 않을 테니까.. 하지만 암호화, 해시, 난수는 전문적으로 들어가면 지향하는 목표가 다른 분야라고 한다.

말이 나왔으니 말인데.. 임의로 생성 가능한 문자열과 이를 hash한 문자열을 혼합하면.. 올바른 번호와 잘못된 번호의 구분이 존재하는 일련번호(serial key) 체계도 생성할 수 있다.
간단하게는 우리나라 주민등록번호가 대표적인 예이다. 검증용으로 쓰이는 마지막 자리 숫자가 hash 함수의 결과값이니까 말이다.

소프트웨어에서 불법 복제를 감지하고 예방하기 위해 발급되는 제품 key도 다 이런 원리로 발급된다. 상업용 소프트웨어야 처음부터 고정된 시리얼 키가 제품 패키지에 들어있으니 사용자 이름과 무관하겠지만, 셰어웨어 등록판을 생성하는 시리얼 키는 사용자의 이름도 공식에 응당 반영된다.

규칙에 어긋난 잘못된 문자열을 입력하면 해당 제품의 설치 프로그램은 에러 메시지를 내뱉으면서 다음 단계로 진행을 하지 않을 것이다. key의 생성 규칙은 그 제품 개발사의 중대한 영업 기밀이다.

하지만 이렇게 수학적인 방법, 소프트웨어적인 방법은 역공학을 통해서 뚫리기도 너무 쉽다. 암호학에서 알고리즘이 아니라 key만 믿어야 한다고 괜히 강조하는 게 아니다.
옛날에 불법 복제 어둠의 경로를 가 보면 도대체 어떻게 알아냈는지 특정 소프트웨어의 제품 key를 생성해 주는 툴이 버젓이 굴러다니곤 했다. 그렇기 때문에 요즘은 이 제품 key가 실제 구매자가 사용하는지의 여부를 제품 개발사 서버로부터 일일이 추가로 확인받곤 한다.

설계 차원에서 결함이 있지 않은 안전한 암호화 알고리즘이라면 key 없이 복호화를 하는 방법이 존재하지 않는다. 그렇기 때문에 이런 암호문은 그냥 a부터 z까지 모든 글자 조합을 무식하게 일일이 대입하는 brute force 방식으로만 풀 수 있다.
패스워드의 길이가 한 글자 늘어날 때마다 공격에 소요되는 시간이 수십 배씩 기하급수적으로 늘어나니.. 이 시간 덕분에 오늘도 인간의 컴퓨팅 세계는 딱히 금융 사고나 개인정보 유출 사고가 별로 없이 안전하게 돌아가고 있다.

하지만 컴퓨터의 계산 성능은 하루가 다르게 향상되고 있고 암호 공격은 병렬화에도 아주 유리한 분야이다.
이런 brute force 공격을 저지하기 위해 요즘 암호를 입력받는 프로그램, 웹사이트 등에서는 암호가 틀릴 때마다 수 초씩 딜레이를 일부러 주고, n번 이상 암호를 틀리면 계정을 정지시키는 조치까지 취한다. 그 어떤 암호 시스템도 하나하나 다 대입해 보는 제일 무식하고 원천적인 전수조사에는 언젠가 뚫릴 수밖에 없는데.. key가 너무 허술하게 만들어져 있으면 거기에 더욱 취약해질 것이다.

3. 공개 키 암호화

지금까지 key를 따로 받지 않는 대표값 변조(해싱), 그리고 key를 받는 대칭 키 암호화까지 얘기가 나왔다. 대칭 키 암호화는 입력 데이터를 받아들이는 방식에 따라 블록 암호화 내지 스트림 암호화로도 나뉘는데, AES/DES 같은 것들은 블록 암호화로 분류된다.
그런데 1970년대에는 이런 것과는 성격이 근본적으로 다른 완전히 새로운 암호화 분야가 개척되었다. 바로 대칭이 아닌 비대칭, 또는 공개 키 알고리즘이라는 개념이 제안되고 개발된 것이다.

왜냐하면 제아무리 날고 기는 복잡 정교한 암호화 알고리즘이 있다 하더라도 그것들은 발신자와 수신자가 모두 동일한 key를 알아야 하고 보안을 위해서는 수시로 교체해야 하고, 그 바뀐 key를 모든 구성원에게 전해 줘야 한다는 원천적인 한계와 위험성이 있기 때문이다. 군대에서 새 암구호를 어떤 절차를 통해 전파하는지를 생각해 보자.

key를 주고 받는 건 암호라는 걸 운용하는 모든 조직이 감내해야 하는 어쩔 수 없는 숙명인 것 같다. 하지만 암호화 때 사용되는 key와 복호화 때 사용되는 key가 다르고(비대칭), 전자는 마음대로 주변에 공개해도 되는(공개 키) 알고리즘은 이런 한계를 극복해 준다. 이런 마법 같은 일이 어떻게 가능할까..?

이 암호화는 수학적 비가역성 내지 난해함에 근거를 두고 있다. 자릿수가 많은 두 수를 곱하는 건 사람의 입장에서 몹시 고된 노가다이겠지만.. 역으로 이미 곱해진 듣보잡 수를 아예 소인수분해 하는 것은.. 뭐 차원이 다를 정도로 난감하고 시간이 오래 걸리는 일일 것이다. 페르마 수 같은 게 n이 조금만 커져도 합성수인 것만 알려졌을 뿐 완전한 소인수분해가 안 된 놈들이 부지기수인 게 이 때문이다.

공개 키 암호화 중 하나로 유명한 RSA는 수십 자리 이상의 엄청나게 큰 소수 둘을 골라서 이 원천으로부터 공개 key와 개인 key pair를 만들어 낸다. 즉, 처음부터 동일한 원천으로부터 두 key 쌍이 계산에 의해 만들어진다는 것이다. 비록 계산이긴 해도 한 key로부터 나머지 key를 역으로 유도하는 것은 무진장 어렵고 시간이 많이 걸린다.

이런 공개 키 암호화는 제약이 크다. 앞서 살펴봤던 재래식(?) 암호화처럼 임의의 메모리 블록이나 문자열을 취급하지는 못하며, 평문과 key, 암호화 결과 모두 그냥 숫자 달랑 하나일 뿐이다. 숫자에다가 문자열에 맞먹는 정보를 담으려면 그 수가 엄청나게 커져야 한다.
그리고 얘는 그런 주제에 계산량이 차원이 다르게 많다. 컴퓨터 친화적인 XOR이나 비트 회전 같은 게 아니라 거대 정수에 대한 산술 연산을 무진장 해야 하기 때문이다.

그렇기 때문에 이런 암호화 알고리즘은 재래식 블록 암호화처럼 몇 MB짜리 데이터 자체를 암호화하는 단순한 용도로 쓸 수 없다.
그 대신 재래식 암호화 알고리즘에다가 돌릴 짤막한 key만을 암호화하는 용도로 병행해서 쓰인다. 멀티스레드 프로그램에서 TLS 슬롯은 공간이 한정되어 있으니 거기에다가 생 데이터를 몽땅 저장하는 게 아니라 그냥 포인터만 저장해 놓는 것과 비슷한 이치랄까..? 마치 손실 압축과 비손실 압축만큼이나 고유한 용도가 있는 셈이다.

https 보안 사이트 내지 인터넷 뱅킹에서 로그인을 할 때 시간이 0.n초나마 랙이 있는 이유는 네트워크 트래픽 때문이 아니라 순수하게 계산 때문에 그렇다. 그때마다 암호 해독을 위해 OpenSSL에 구현된 BigInt 같은 라이브러리의 코드가 실행되면서 큰 수 연산과 값 비교가 행해진다고 생각하면 되겠다.

공개 키 암호화로서 RSA가 아주 유명하지만 이런 소수와 소인수분해 말고 타원곡선이나 이산로그 같은 다른 어려운 연산에 기반을 둔 알고리즘도 있다.
이 암호화 기술은 인터넷의 발달과 더불어 우리의 생활을 크게 바꿔 놓았다. key를 위험하게 통째로 주고받지 않아도 되는 암호화 덕분에 인터넷 상으로 금융 거래도 할 수 있게 되고 디지털 서명, 인증서라는 것도 존재할 수 있게 됐기 때문이다!

보통은 공개 key로 암호화를 해서 개인 key로 복호화를 하는데, 반대로 어떤 문서를 개인 key로 암호화하고 공개 key로 복호화하게 하면 된다. 그러면 이 문서는 누구나 열람은 가능하지만, 만든 사람은 그 공개 key에 대응하는 개인 key의 소유자밖에 없다는 것이 입증된다. 놀랍지 않은가?

hash가 어떤 데이터가 원본과 동일한지 무결성을 보장한다면, 공개 key 암호화는 어떤 데이터가 반드시 특정인으로부터 만들어졌고 변조되지 않았다는 것을 보장할 수 있다.
도장이고 자필 서명이고 자물쇠와 열쇠 같은 모든 실물은 조작이 가능하며 컴퓨터야 뭐 0과 1 무엇이건 해킹이 가능한 디지털 세상이다. 이런 바닥에서 믿을 것은 수학적인 비가역성밖에 없어진다는 것이다.

이 세상에서 생명을 다루는 의료 다음으로 중요하고 착오가 절대로 없어야 하는 크리티컬한 임무는 아무래도 돈 거래, 기밀 거래일 텐데, 이 정도 기반은 갖춰진 뒤에야 인터넷이 안전하게 돌아가고 있다. 그러나 초창기에 인터넷은 기반 프로토콜 차원에서 이런 암호화 알고리즘이 제공되지 않았다.

그렇기 때문에 전자상거래나 인터넷 뱅킹을 남보다 일찍 서둘러 구현하려면 특정 운영체제에 종속적인 온갖 비표준 편법 기술이 동원돼야 했다. 오죽했으면 2000년대 초에 SEED 같은 알고리즘까지 개발한 걸 보면 공개 키뿐만 아니라 대칭 키 암호화까지 모두 허술했던가 보다.
허나 이게 바로 우리나라 특유의 IE + ActiveX 의존이라는 독이 되어서 오늘에 이르고 있다. 일본이 일찍부터 철도 왕국이 되긴 했지만 협궤 때문에 발목 잡힌 것과 비슷한 현상이랄까..?

이상이다. 인증서가 어떻고 공개 키, 개인 키, 디지털 서명 이러는 바닥은 통상적인 hash나 블록 암호화와는 영역이 상당히 다르다는 것, 그리고 이런 공개 키 암호화 덕분에 인터넷 보안 수준의 차원이 달라졌다는 것이 핵심이다. 이 바닥도 날고 기는 괴수들이 너무 많다..;;

Posted by 사무엘

2021/03/31 08:33 2021/03/31 08:33
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1871

C/C++은 성능을 위해 컴파일러나 언어 런타임이 프로그래머의 편의를 위해 뭔가를 몰래 해 주는 것을 극도로 최소화한 언어이다. 꾸밈 없고 정제되지 않은 '날것 상태 raw state'에다가 고급 프로그래밍 언어의 패러다임과 문법만을 얹은 걸 추구하다 보니, '초기화되지 않은 쓰레기값'이라는 게 존재하는 거의 유일한 언어이기도 하다.

같은 프로그램이라도 이제 막 선언된 변수나 할당된 메모리 안에 무슨 값이 들어있을지는 컴퓨터 운영체제의 상태에 따라서 그때 그때 달라진다. 반드시 0일 거라는 보장은 전혀 없다. 오히려 0 초기화는 별도의 CPU 부담이 필요한 인위적인 작업이다. global/static에 속하는 메모리만이 무조건적인 0 초기화가 보장된다.

그렇다고 쓰레기값이라는 게 완벽하게 예측 불가이면서 통계적인 질서를 갖춘 난수인 것도 물론 아니다.
그리고 Visual C++에서 프로그램을 debug 세팅으로 빌드하면 쓰레기값이라는 게 크게 달라진다. C++ 개발자라면 이 사실을 이미 경험적으로 충분히 알고 있을 것이다.

1. 갓 할당된 메모리의 기본 쓰레기값: 0xCC(스택)와 0xCD(힙)

가장 먼저, 스택에 저장되는 지역변수들은 자신을 구성하는 바이트들이 0xCC로 초기화된다. 다시 말해 디버그 빌드에서는 int x,y라고만 쓴 변수는 int x=0xCCCCCCCC, y=0xCCCCCCCC와 얼추 같게 처리된다는 것이다. 디스어셈블리를 보면 의도적으로 0xCC를 대입하는 인스트럭션이 삽입돼 들어간다.

0은 너무 인위적이고 유의미하고 깔끔한(?) 값 그 자체이고, 그 근처에 있는 1, 2나 0xFF도 자주 쓰이는 편이다. 그에 비해 0xCC는 형태가 단순하면서도 현실에서 일부러 쓰일 확률이 매우 낮은 값이다. 그렇기 때문에 여기는 초기화되지 않은 쓰레기 영역이라는 것을 시각적으로 곧장 드러내 준다.

int a[10], x; a[x]=100; 같은 문장도 x가 0으로 깔끔하게 자동 초기화됐다면 그냥 넘어가지만, 기괴한 쓰레기값이라면 곧장 에러를 발생시킬 것이다.
또한, 복잡한 클래스의 생성자에서 값이 대입되어 초기화된 멤버와 그렇지 않은 멤버가 뒤섞여 있을 때, 0xCC 같은 magic number는 탁월한 변별력을 발휘한다.

타겟이 align을 꼼꼼하게 따지는 아키텍처라면, 쓰레기값을 0x99나 0xDD 같은 홀수로 지정하는 것만으로도 초기화되지 않은 포인터 실수를 잡아낼 수 있다. 32비트에서 포인터값의 최상위 비트가 커널/사용자 영역을 분간한다면, 최하위 비트는 align 단위를 분간할 테니 말이다. 뭐 0xCC는 짝수이다만..

0xCC라는 바이트는 x86 플랫폼에서는 int 3, 즉 breakpoint를 걸어서 디버기의 실행을 중단시키는 명령을 나타내기도 한다. 그래서 이 값은 실행 파일의 기계어 코드에서 align을 맞추기 위해 공간만 차지하는 잉여 padding 용도로 위해 듬성듬성 들어가기도 한다.
Visual C++ 6 시절엔 거기에 말 그대로 아무 일도 안 하는 nop를 나타내는 0x90이 쓰였지만 2000년대부터는 디버깅의 관점에서 좀 더 유의미한 작용을 하는 0xCC로 바뀐 듯하다. 정상적인 상황이라면 컴퓨터가 이 구역의 명령을 실행할 일이 없어야 할 테니까..

다만, 힙도 아니고 스택 지역변수의 내용이 데이터가 아닌 코드로 인식되어 실행될 일이란 현실에서 전혀에 가깝게 없을 테니, 0xCC는 딱히 x86 기계어 코드를 의식해서 정해진 값은 아닐 것으로 보인다.

Visual C++의 경우, 스택 말고 malloc이나 new로 할당하는 힙(동적) 메모리는 디버그 버전에서는 내용 전체를 0xCD로 채워서 준다. 0xCC보다 딱 1 더 크다. 아하~! 이 값도 평소에 디버그 하면서 많이 보신 적이 있을 것이다.
힙의 관리는 컴파일러 내장이 아니라 CRT 라이브러리의 관할로 넘어기도 하니, 0xCD라는 값은 라이브러리의 소스인 dbgheap.c에서도 _bCleanLandFill이라는 상수명으로 확인할 수 있다.

2. 초기화되지 않은 스택 메모리의 사용 감지

C/C++ 언어는 지역변수의 값 초기화를 필수가 아닌 선택으로 남겨 놓았다. 그러니 해당 언어의 컴파일러 및 개발툴에서는 프로그래머가 초기화되지 않은 변수값을 사용하는 것을 방지하기 위해, 디버그용 빌드 한정으로라도 여러 안전장치들을 마련해 놓았다.
그걸 방지하지 않고 '방치'하면 같은 프로그램의 실행 결과가 debug/release별로 달라지는 것을 포함해 온갖 골치아픈 문제들이 발생해서 프로그래머를 괴롭히게 되기 때문이다.

int x; printf("%d", x);

이런 무식한 짓을 대놓고 하면 30년 전의 도스용 Turbo C에서도 컴파일러가 경고를 띄워 줬다. Visual C++의 에러 코드는 C4700. 그랬는데 한 Visual C++ 2010쯤부터는 이게 경고가 아니라 에러로 바뀌었다.
그리고 그 뿐만이 아니다.

int x;
if( some_condition_met(...)) x=0;
printf("%d", x);

이렇게 문장을 약간만 꼬아 놓으면 초기화를 전혀 안 하는 건 아니기 때문에 컴파일 과정에서의 C4700을 회피할 수 있다. 하지만 보다시피 if문의 조건이 충족되지 않으면 x가 여전히 초기화되지 않은 채 쓰일 수 있다. 이건 정적 분석 정도는 돌려야 감지 가능하다.
(그런데, 글쎄.. 함수의 리턴이 저런 식으로 조건부로 불완전하게 돼 있으면 컴파일만으로도 C4715 not all control paths return value 경고가 뜰 텐데.. 비초기화 변수 접근 체크는 그 정도로 꼼꼼하지 않은가 보다.)

Visual C++은 /RTC라고 디버그용 빌드에다가 run-time check라는 간단한 검사 기능을 추가하는 옵션을 제공한다. 함수 실행이 끝날 때 스택 프레임 주변을 점검해서 버퍼 오버런을 감지하는 /RTCs, 그리고 지역변수를 초기화하지 않고 사용한 것을 감지하는 /RTCu.

사용자 삽입 이미지

저 코드를 Visual C++에서 디버그 모드로 빌드해서 실행해서 if문이 충족되지 않으면 run-time check failure가 발생해서 프로그램이 정지한다. 다만, 이 메모리는 초기화만 되지 않았을 뿐 접근에 법적으로 아무 문제가 없는 스택 메모리이다. 할당되지 않은 메모리에 접근해서 access violation이 난 게 아니다. 심각한 시스템/물리적인 오류가 아니라 그저 의미· 논리적인 오류이며, 쓰기를 먼저 하지 않은 메모리에다가 읽기를 시도한 게 문제일 뿐이다.

그러니 이 버그는 해당 메모리 자체에다가 시스템 차원의 특수한 표식을 해서 잡아낸 게 아니며, 논리적으로 매우 허술하다. (0xCC이기만 하면 무조건 스톱.. 이럴 수도 없는 노릇이고!)
문제의 코드에 대한 디스어셈블리를 보면 if문이 만족되지 않으면 printf으로 가지 않고 그냥 곧장 RTC failure 핸들러를 실행하게 돼 있다.

void do_nothing(int& x) {}

int x; do_nothing(x); printf("%d", x);

그렇기 때문에 요렇게만 해 줘도 RTC를 회피하고 x의 쓰레기값을 얻는 게 가능하다. 글쎄, 정교한 정적 분석은 이것도 지적해 줄 수 있겠지만, 포인터가 등장하는 순간부터 메모리 난이도와 복잡도는 그냥 하늘로 치솟는다고 봐야 할 것이다.

하물며 처음부터 포인터로만 접근하는 힙 메모리는 RTC고 뭐고 아무 안전 장치가 없다. int *p에다가 new건 malloc이건 값이 하나 들어간 것만으로도 초기화가 된 것이거늘, 그 주소가 가리키는 p[0], p[1] 따위에 쓰레기값(0xCD)이 있건 0이 있건 알 게 무엇이겠는가????

나도 지금까지 혼동하고 있었는데, 이런 run-time check failure는 run-time error와는 다른 개념이다. 순수 가상 함수 호출 같은 건 C/C++에 존재하는 얼마 안 되는 run-time error의 일종이고 release 빌드에도 포함돼 들어간다. 하지만 RTC는 debug 빌드 전용 검사이다.

그러니 버퍼 오버런을 감지하는 보안 옵션이 /RTC만으로는 충분하지 않고 /GS가 따로 있는 것이지 싶다. /GS는 release 빌드에도 포함돼 있으며, 마소에서는 보안을 위해 모든 프로그램들이 이 옵션을 사용하여 빌드할 것을 권하고 있다.

3. 해제된 힙 메모리: 0xDD(CRT)와 0xFEEE(???)

일반적인 프로그래머라면 동적으로 할당받은 힙 메모리를 free로 해제했을 때, 거기를 가리키는 메모리 영역이 실제로 어떻게 바뀌는지에 대해 생각을 별로 하지 않는다. 사실, 할 필요가 없는 게 정상이기도 하다.
우리 프로그램은 free를 해 준 주소는 신속하게 영원히 잊어버리고, 그 주소를 보관하던 포인터는 NULL로 바꿔 버리기만 하면 된다. free 해 버린 주소를 또 엿보다가는 곧바로 메모리 에러라는 천벌을 받게 될 것이다.

그런데 실제로는, 특히 디버그 모드로 빌드 후 프로그램을 디버깅 중일 때는 free를 한 뒤에도 해당 메모리 주소가 가리키는 값을 여전히 들여다볼 수 있다. 들여다볼 수 있다는 말은 *ptr을 했을 때 access violation이 발생하지 않고 값이 나온다는 것을 의미한다.
이 공간은 나중에 새로운 메모리 할당을 위해 재사용될 수야 있다. 하지만 사용자가 디버깅의 편의를 위해 원한다면 옵션을 바꿔서 재사용되지 않게 할 수도 있다. (_CrtSetDbgFlag(_CRTDBG_DELAY_FREE_MEM_DF) 호출)

뭐, 메모리를 당장 해제하지 않는다고 해서 free 하기 전의 메모리의 원래 값까지 그대로 남아 있지는 않는다. Visual C++의 디버그용 free/delete 함수는 그 메모리 블록의 값을 일부러 0xDD (_bDeadLandFill)로 몽땅 채워 넣는다. 여기는 할당되었다가 해제된 영역임을 이런 식으로 알린다는 것이다.

실제로, free된 메모리가 곧장 흔적도 없이 사라져서 애초에 존재하지도 않았던 것처럼 접근 불가 ?? 로 표시되는 것보다는 0xDD라고 디버거의 메모리 창에 뜨는 게 dangling pointer 디버깅에 약간이나마 더 도움이 될 것이다. 이 포인터가 처음부터 그냥 쓰레기값을 가리키고 있었는지, 아니면 원래는 valid하다가 지칭 대상이 해제되어 버린 것인지를 분간할 수 있으니 말이다.

그런데 본인은 여기서 개인적으로 의문이 들었다.
본인은 지난 20여 년에 달하는 Visual C++ 프로그래밍과 메모리 문제 디버깅 경험을 떠올려 봐도.. 갓 할당된 쓰레기값인 0xCC와 0xCD에 비해, 0xDD를 본 적은 전혀 없는 건 아니지만 매우 드물었다.

dangling pointer가 가리키는 메모리의 값은 0xD?보다는 0xF?였던 적이 훨씬 더 많았다. 더 구체적으로는 2바이트 간격으로 0xFEEE (0xEE, 0xFE)이다.

사용자 삽입 이미지

인터넷 검색을 해 보니.. 이건 놀랍게도 CRT 라이브러리가 채워 넣는 값이 아니었다. free/delete가 궁극적으로 호출하는 Windows API 함수인 HeapFree가 메모리를 정리하면서 영역을 저렇게 바꿔 놓았었다. 더구나 CRT에서 0xDD로 먼저 채워 넣었던 영역을 또 덮어쓴 것이다.
이 동작에 대해서 놀라운 점은 저게 전부가 아니다.

(1) 0xFEEE 채우기는 프로그램을 Visual C++ 디버거를 붙여서(F5) 실행했을 때만 발생한다. debug 빌드라도 디버거를 붙이지 않고 그냥 Ctrl+F5로 실행하면 0xFEEE가 생기지 않는다. 그리고 release 빌드라도 디버거를 붙여서 실행하면 0xFEEE를 볼 수 있다.

(2) 더 놀라운 점은.. 내가 집과 직장 컴퓨터를 통틀어서 확인한 바로는 저 현상을 볼 수 있는 건 Visual C++ 2013 정도까지이다. 2015부터는 debug 빌드를 디버거로 붙여서 돌리더라도 0xFEEE 채움이 발생하지 않고 곧이곧대로 0xDD만 나타난다~!

운영체제가 정확하게 어떤 조건 하에서 0xFEEE를 채워 주는지 모르겠다. 인터넷 검색을 해 봐도 정확한 정보가 나오는 게 의외로 없다.
하필 Visual C++ 2015부터 저런다는 것은 CRT 라이브러리가 Universal CRT니 VCRuntime이니 하면서 구조가 크게 개편된 것과 관계가 있지 않으려나 막연히 추측만 해 볼 뿐이다.

여담이지만 HeapAlloc, GlobalAlloc, LocalAlloc은 연달아 호출했을 때 돌아오는 주소의 영역이 그리 큰 차이가 나지 않으며, 내부 동작 방식이 모두 비슷해진 것 같다. 물론 뒤의 global/local은 fixed 메모리 할당 기준으로 말이다.

4. 힙 메모리 영역 경계 표시용: 0xFD와 0xBD

0xCD, 0xDD, (0xFEEE) 말고 heap 메모리 주변에서 볼 수 있는 디버그 빌드용 magic number 바이트로는 0xFD _bNoMansLandFill와 0xBD _bAlignLandFill가 더 있다.

얘들은 사용자가 요청한 메모리.. 즉, 0xCD로 채워지는 그 메모리의 앞과 뒤에 추가로 고정된 크기만큼 채워진다. Visual C++ CRT 소스를 보면 크기가 NoMansLandSize인데, 값은 4바이트이다. 사용자가 요청한 메모리 크기에 비례해서 채워지는 0xCD와 0xDD에 비하면 노출 빈도가 아주 작은 셈이다. 특히 0xBD는 0xFD보다도 더욱 듣보잡인 듯..

애초에 얘는 사용자가 건드릴 수 있거나 건드렸던 공간이 아니며 그 반대이다. 사용자는 0xCD로 채워진 공간에다가만 값을 집어넣어야지, 앞뒤  경계를 나타내는 0xFD를 건드려서는 안 된다.
CRT 라이브러리의 디버그용 free/delete 함수는.. 힙을 해제할 때 이 0xFD로 표시해 놨던 영역이 값이 바뀌어 있으면 곧장 에러를 출력하게 돼 있다.

그리고 예전에 메모리를 해제해서 몽땅 0xDD로 채워 놨던 영역도 변조된 게 감지되면 _CrtCheckMemory 같은 디버깅 함수에서 곧장 에러를 찍어 준다. 그러니 0xDD, 0xFD, 0xBD는 모두 오류 검출이라는 용도가 있는 셈이다. 0xCC와 0xCD 같은 쓰레기값 영역은 쓰지도 않고 곧장 읽어들이는 게 문제이지만, 나머지 magic number들은 건드리는 것 자체가 문제이다.

그리고 얘들은 heap 메모리를 대상으로 행해지는 점검 작업이다. 이런 것 말고 스택 프레임에다가 특정 magic number를 둬서 지역변수 배열의 overflow나 복귀 주소 변조를 감지하는 것은 별도의 컴파일러 옵션을 통해 지원되는 기능이다. 요것들은 힙 디버그 기능과는 별개이며, 보안 강화를 위해 release 빌드에도 포함되는 게 요즘 추세이다.

이상이다.
파일 포맷 식별자 말고 메모리에도 디버깅을 수월하게 하기 위해 쓰레기값을 가장한 이런 특수한 magic number들이 쓰인다는 게 흥미롭다. Windows의 Visual C++ 외의 다른 개발 환경에서는 디버깅을 위해 어떤 convention이 존재하는지 궁금해진다.

사실, 16진수 표기용인 A~F에도 모음이 2개나 포함돼 있고 생각보다 다양한 영단어를 표현할 수 있다. 거기에다 0을 편의상 O로 전용하면 모음이 3개나 되며, DEAD, FOOD, BAD, FADE, C0DE 정도는 거뜬히 만들어 낸다. 거기에다 FEE, FACE, FEED, BEEF 같은 단어도.. 유의미한 magic number나 signature를 고안하는 창의력을 발산하는 데 쓰일 수 있다.
그러고 보니 아까 0xFEEE도 원래 free를 의도했는데 16진수 digit에 R은 없다 보니 불가피하게 0xFEEE로 대충 때운 건지 모르겠다.

Posted by 사무엘

2021/02/11 08:36 2021/02/11 08:36
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1853

1. 텍스트 에디터

macOS의 워드 프로세서 겸 에디터인 TextEdit은 신기하게도 '자동 줄 바꿈'을 끄는 기능이 없다...! 개인적으로 굉장한 문화 충격을 느꼈다. 줄 바꿈을 창이 아닌 용지를 기준으로 하게 하고 용지의 폭을 9999로 지정하는 간접적인 방법만 동원할 수 있다.

하긴 macOS는 터미널 창도 창 크기에 맞춰 줄 정렬을 꼬박꼬박 다시 해 주고 xcode의 코드 에디터에서도 자동 줄 바꿈이 지원되니.. 그쪽 바닥은 분위기가 전반적으로 wrap에 친화적인 것 같다.

2. 텍스트 뷰어

에디터처럼 파일을 linked list 형태로 재구성하지 말고 수백 MB~수 GB의 파일이라도 O(1) 상수 시간으로 즉시 읽어들이는 텍스트 뷰어가 좀 있으면 좋겠다. 당장 화면에 표시해야 하는 맨 앞이나 맨 뒷부분만 줄 바꿈과 탭 적용을 한 뒤, 나머지 화면에 안 보이는 부분에 대한 줄 수 계산, 글자 폭 계산 같은 건 그때 그때 백그라운드로 진행한다.
파일의 앞부분이나 맨 뒷부분만 신속하게 조회 가능하되, 필요하면 다른 부분으로 스크롤이나 텍스트 검색도 가능해야 한다. 텍스트 수정은..?? 파일의 크기를 변경하지 않는(= 삽입, 삭제) 변경만 있어도 좋다.

유닉스의 tail 명령은 뒷부분 조회는 가능하지만 내가 원하는 모든 기능이 들어있지는 않다.
워드 프로세서가 아니라 텍스트 에디터도 전문적인 개발 분야이듯.. 텍스트 뷰어만으로도 별개의 개발 분야가 될 수 있을 것 같다. 방대한 로그 파일 같은 건 이런 프로그램을 이용해서 열람해야 할 것이다.

3. 그래픽 에디터

(1) 요즘 세상에 2, 16, 256색 팔레트 기반의 이미지를 전문적으로 처리 가능한 그래픽 에디터가 살아 있기는 한가 모르겠다. 수요가 매우 드물어졌지만 그래도 전혀 없지는 않을 텐데 말이다. 나는 그런 일이 생기면 닥치고 Paint Shop Pro 구버전으로 고고씽 한다..;;

(2) 한편, 세상이 하도 많이 바뀌어서 손실 압축 코덱 기반의 통상적인 동영상이 gif 움짤보다도 더 가볍고 효율이 좋아지는 지경이 됐다. 전자는 jpg처럼 양자화 과정에서 손실이 발생하고, 후자는 디더링 과정에서 손실이 발생한다.
무손실 압축 기반으로 트루컬러가 지원되는 깔끔한 소규모 동영상 포맷이 등장하고 그게 Windows의 애니메이션 컨트롤 같은 데서도 지원됐으면 좋겠다. 일반적인 그래픽 툴로도 쉽게 만들 수 있고 말이다.

4. 파일 관리 셸

프로그래밍을 업으로 삼는 개발자 내지 파워 유저들은 갓 설치한 운영체제의 GUI 기반 파일 관리 셸에서 거의 공통으로 제일 먼저 설정을 변경하는 것이 있다. 바로 (1) 파일 목록에서 확장자까지 표시하도록 하고, (2) 숨김 파일도 나오게 하는 것이다.

  • Windows의 탐색기(Explorer): 예전에는 보기 옵션 대화상자를 꺼내고 번거로운 단계를 거쳐야 했다. 하지만 Windows 8인가 10쯤부터는 '보기' 탭에 체크 옵션이 바로 표시되기 때문에 접근하기 편해졌다.
  • macOS의 Finder: 아마 내 기억이 맞다면 어디 설정 파일을 텍스트 에디터로 열어서 고쳐야 하지 싶다. GUI에서 이런 설정을 변경할 수 있지는 않다. 구체적인 방법은 검색해 보면 나올 것이다.
  • 리눅스: 셸 엔진이 무엇이냐에 따라 차이가 있을 수 있지만(GNOME, KDE??).. 리눅스는 역시 GUI 셸이라도 기본적으로 파일의 확장자가 꼬박꼬박 표시되고 있지 싶다.

이런 사소한 디테일도 세 운영체제의 정책이 서로 차이가 있는 셈이다.
컴퓨터의 내부 디테일을 모조리 파악하고 싶어하는 사람 입장에서는 파일 확장자를 도대체 왜 숨기는지 답답함을 느낄 것이다. 아이콘은 확장자의 기능을 완벽하게 대체하지 못하기 때문이다.

하지만 일반인이나 컴맹의 입장에서는 필요 이상으로 쓸데없이 자세한 정보를 가능한 한 숨기는 게 바람직하다. 그러니 확장자나 숨김 파일을 취급하는 방식은 앞으로도 이렇게 옵션과 재량의 영역에 머무를 것으로 보인다.

5. 웹브라우저

요즘은 웹페이지 내부에서도 지도나 하드카피 문서(구글 도서 검색 같은..)를 조회하고 영역을 Ctrl+휠로 확대/축소할 수 있다.
그런데 똑같이 키보드 포커스를 주고 Ctrl+휠을 굴렸을 때 그 영역만이 확대/축소될 때가 있고, 아니면 웹페이지 전체가 확대/축소되어 버릴 때가 있다. 개인적으로 정확한 패턴이나 조건은 아직 모르겠다. 사용하는 브라우저와 이용하는 사이트가 무엇이냐에 따라서 케바케인 것 같다.

확대/축소에 이렇게 중의성이 발생한 게 참 웃긴데.. 사용자가 원하는 결과는 대부분의 경우 전자, 즉 그 영역만 확대/축소되는 것이다. 웹브라우저 내지 웹사이트를 개발할 때 이런 동작과 사용자 경험 쪽도 고려가 됐으면 좋겠다.

6. 요즘 Windows 10 근황

  • 언제부턴가 시작 메뉴와 작업 표시줄의 배경색이 Windows 10 특유의 검정이 아니라 밝은 회색으로 바뀐 컴퓨터가 눈에 띄기 시작했다. 싸제 테마로 customize를 한 건지 궁금했는데.. 그건 아니고 버전 1903부터 밝은 색 테마가 정식으로 추가된 거라고 한다.
  • 집과 회사 컴퓨터를 몇 대 살펴보니.. xps/oxps 확장자가 자체 viewer로 연결되어 있지 않은 곳이 좀 눈에 띈다. 정작 xps/oxps 파일을 생성해 주는 가상 프린터 드라이버는 다들 기본으로 설치돼 있는데, viewer가 없거나 연결돼 있지 않은 게 말이 되는지..?? 어디 좀 착오가 있는 것 같다.
  • Windows 10이 나온 지 벌써 5년이 돼 간다. 대부분의 운영체제 설정 기능들이 데스크톱 UI인 제어판(Control Panel)에서 메트로 UI인 Settings로 갈아탔지만, 키보드의 반복 속도를 설정하는 기능은 아무리 눈 씻고 검색해도 없는 것 같다.
    Settings에는 키보드 설정과 입력 언어 설정이 별 구분 없이 뒤섞여 있으며, 제어판 한구석에 처박힌 구닥다리 제어판 애플릿을 꺼내야 변경 가능하다.
  • 그리고 내 경험상, 처음 사용하는 컴퓨터들은 마우스 포인터 뒷배경에 그림자 효과가 적용돼 있지 않은 것 같다. 왜 뺐는지..?? 이걸 지정하는 것도 Settings에는 없고, 제어판 애플릿을 따로 열어야 한다.

7. 스플래시 화면

덩치와 규모가 좀 있는 소프트웨어라면 실행되어 로딩 중일 때 일명 스플래시 화면이라는 게 잠시 나타났다가 사라지곤 한다. 얘는 표시하는 내용이 About 대화상자와 좀 겹치는 구석이 있지만(제품 명칭, 버전, 저작권자..), 그 대화상자보다는 화려한 그림의 비중이 더 크다.

뭐, 요즘은 정말로 어마어마하게 방대 거대해서 로딩 시간이 긴 프로그램이라든지, 10년 20년 전부터 화려한 스플래시 화면이 컨셉이요 전통이었던 프로그램이 아닌 이상, 굳이 스플래시 화면을 넣지는 않는 편이다. 그냥 바로 본론으로 들어가서 자기 화면만 띄운다.
컴퓨터의 성능이 갈수록 좋아지면서 프로그램이 구동되는 데 걸리는 시간도 충분히 짧아졌고, 또 요즘은 추세도 새 프로그램의 구동을 요란하게 알리는 게 아니기 때문이다.

예를 들어, 설치 프로그램만 해도 화면 전체를 자기 창으로 꽉 채우고 파랑-검정 그러데이션을 띄우던 유행은 이미 20년도 더 전, 2000년대 초반쯤부터 없어졌고 간단한 마법사로 바뀌었다.
그리고 Windows 8쯤부터는 tada.wav 이래로 오랜 전통이던 운영체제의 시작 음향도 없어졌다. 이런 식이다.

옛날에 Windows 95 시절에는 딱 한 번, 워드패드도 실행될 때 스플래시 화면이 잠깐 나타나던 적이 있었다. 그 자그마한 프로그램에도 말이다.;; 물론 98과 그 이후부터는 싹 없어졌고 다시는 부활하지 않았다.
오늘날 마소 제품들 중에 Office나 Visual Studio 같은 건 실행될 때 스플래시 화면이 뜬다. 그런데 과거에 비해 중요한 변화가 생긴 게 있다.

옛날 버전들은 스플래시 화면에다가 마우스 포인터를 가져가면 모래시계 모양으로 바뀌었다.
그러나 Office는 2010부터, VS는 2012부터.. 마우스 포인터를 가져가도 모래시계가 아니라 일반 화살표 모양이 유지되며, 스플래시 화면을 마우스로 드래그 하면 그 화면을 딴 데로 이동시킬 수도 있다.

즉, 스플래시 화면에 대한 사용자 반응성을 더 개선한 것이다. 스플래시 화면이 들어갈 정도로 방대한 소프트웨어를 개발하는 분이라면 이런 면모도 생각해 볼 필요가 있다. 뭐, 본인이 개발하고 있는 날개셋 한글 입력기는 스플래시 화면이 필요할 정도로 방대한 프로그램이 전혀 아니기 때문에 해당사항이 없다.

8. ESC 또는 Alt+F4

Visual Studio는 '닷넷'으로 바뀌었던 200x 버전 시절부터 '시작 페이지'라는 것을 제공해 왔는데, 2019부터 이걸 그냥 대화상자로 대체했다. 그런데 이거 동작 방식이 꽤 재미있다.
대화상자를 ESC를 눌러서 닫으면 프로그램 실행이 계속 진행되어 정식 IDE 창이 뜬다. 하지만 대화상자를 Alt+F4 또는  [X] 버튼 클릭으로 종료하면.. 프로그램이 통째로 종료된다. 이 차이점을 눈치 챈 분 혹시 계시는가?

Windows에서 ESC와 Alt+F4는 차이점이 매우 미미하다. 대화상자를 '취소'로 닫을 수 있는 건 공통인데 후자는 전자의 상위 호환으로, 프로그램 main 창을 종료하고 시스템 종료까지 가능하다는 차이가 있을 뿐이다.
그리고 프로그램의 대화상자는 자신이 ESC로 닫혔는지 Alt+F4로 닫혔는지 같은 걸 일반적으로 분간할 수 없다. WM_CLOSE 내지 IDCANCEL 메시지가 오는 건 동일하기 때문이다.

그런데 굳이 둘을 구분해서 동작한다니.. by design인 걸까?
지금 메모장에서 파일을 저장하지 않고 종료했을 때 나타나는 "....를 저장할까요?" 메시지 대화상자를 Alt+F4로 닫으면 ESC로 닫았을 때와 달리 저장 대화상자가 뜬다. 이는 메시지 대화상자가 MessageBox가 아닌 TaskDialog 기반으로 바뀐 10여 년 전 Windows Vista 때부터 생긴 버그인데, 아직까지도 여전하고 고쳐지지 않았다..;;

ESC와 Alt+F4의 동작이 다른 프로그램을 메모장 이후로 처음으로 하나 더 발견하게 됐다.

9. 버전 넘버링

마소는 1990년대부터 2000년대까지는 Windows, Office, Visual Studio 같은 제품을 버전업할 때마다 외형 비주얼도 그야말로 널뛰기 하듯이 바꾸는 게 유행이었다. 그러나 2010년대 중후반부터는 이제 어지간히 만들 것들은 다 만들었는지 그런 유행이 사실상 끝났다.

그리고 버전 번호도 옛날처럼 과감하게 성큼성큼 올라가지 않고 있다. 글쎄, 웹브라우저들은 크롬의 주도 하에 버전이 자비심 없이 막 올라가는 중이지만 마소 제품들은 그렇지 않다. 다음 사례들을 생각해 보라.

  • Windows: 잘 아시다시피 지난 2015년부터 주 버전 및 브랜드는 Windows 10으로 고정돼 버렸으며, 이제는 연도/월이 기재된 별도의 하위 버전만 올리고 있다. (그래도 서버 제품군의 경우, 2016에 이어 2019를 따로 내놓은 듯하던데.. 연도 기반 네이밍의 의미가 많이 퇴색했다.)
  • Office: 2016과 2019, 그리고 365까지 모두 16.x 버전으로 동일하다.
  • Visual Studio: 최신 2019는 버전 번호가 Office와 마찬가지로 16.x이다. 그리고 내부적으로 통용되는 _MSC_VER 값은 2015까지는 100씩 증가해서 1900에 도달했지만, 다음 2017은 1910, 2019는 1920이 되어서 10씩만 증가하고 있다.
  • .NET Framework: 10년 전인 2010년에 4.5가 나왔지만 10년째 4.x 버전을 졸업하지 않고 있다. Windows 10과 함께 4.6이 나왔고 최신 버전에서도 그냥 4.8대이다.
  • DirectX: Windows 10과 함께 버전 12.x가 나왔으며, 12라는 숫자가 앞으로 더 올라갈 것 같지는 않다.
  • Internet Explorer, Media Player: 얘들은 최소한의 보안 패치만 하지 후속 개발 자체가 중단된 레거시이다. 버전 역시 각각 11, 12에서 멈추고 봉인됐다.

지난 2~30년 동안 PC용 소프트웨어들은 기술이 하도 많이 발전하고 상향평준화하다 보니.. 그냥 무료 서비스 아니면 기간제 구독형으로 바뀌는 추세인 것 같다. 그래서 MS Office도 이제 20xx 같은 연도가 붙은 정규 릴리스 대신 슬슬 구독형을 밀고 있으며, Adobe의 비싼 그래픽 툴들도 진작에 구독형으로 바뀌었다.
Visual Studio는 기본적인 IDE와 컴파일러의 경우, 인디 개발자를 대상으로는 사실상 완전히 무료로 풀렸고, 일정 규모 이상의 인원을 갖춘 기업을 대상으로만 유료이다.

소프트웨어가 구독형으로 바뀌었으니 새 버전 출시와 업데이트도 예전보다 훨씬 더 자주 부담 없이 수시로 행해진다. 거창하게 서비스 팩이니 뭐니 하는 것도 필요하지 않다. Visual Studio만 해도 예전엔 상상도 못 할 정도로 시도 때도 없이 업데이트를 하라고 뜬다. 16.5.0 다음으로 16.5.1 같은 식..
이런 추세와 달리, 한 카피당 사용권 얼마 같은 전통적인 방식으로 유료 소프트웨어를 end-user에게 판매하는 개발자· 개발사와 제품들이 앞으로 얼마나 더 남아 있을지 궁금하다.

Posted by 사무엘

2020/08/14 08:35 2020/08/14 08:35
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1784

1. software is licensed, not sold

자동차의 소유 내지 운전 면허하고, 소프트웨어의 사용권은 공통점과 차이점을 비교해서 같이 생각해 볼 만한 사항인 것 같다. 자동차는 도난 방지 기능이 있고, 소프트웨어는 불법 복제 방지 기능이 있기 때문이다.

전자의 경우 옛날에는 전통적으로 물리적인 열쇠에만 의존하다 보니 보안이 상대적으로 취약했다. 수천 대 중 한 대꼴로 자물쇠 패턴이 일치하는 차량이 존재하기 때문에 그런 차는 내 키로 문을 열 수 있었다. 컴퓨터로 치면 마치 hash의 충돌과 비슷한 상황이라 하겠다.
그리고 영화 테이큰에서도 보듯이 열쇠 구멍을 적당히 쑤셔서 문을 따고, 비정상적인 방법으로 스타터 모터에 전기 자극을 줘서 시동을 걸 수도 있었다.

이런 상황을 막기 위해 과거에는 3rd-party 업체에서 개발한 싸제 도난 방지 시스템이 많이 쓰였다. 지정된 인증을 통과하지 않으면 물리적인 열쇠만으로 문을 따거나 시동을 걸 수 없으며, 오히려 경보음이 울리게 하는 것 말이다. 지금이야 이 정도 도난 방지 기능이 들어간 스마트키는 옵션이 아니라 자동차 제조사에서 기본으로 제공해 주는 영역이 됐다.

그럼 소프트웨어는 어떨까?
과거에는 좀 묵직하고 규모가 있는 제품은 병렬 포트에 락을 꽂는 것(..!)부터 시작해 하드웨어· 소프트웨어적인 온갖 방법으로 "귀하(= 소프트웨어 개발자/개발사)의 소중한 자산을 안전하게 보호하십시오"라고 광고하는 복제 방지 솔루션이 있었다. 하지만 그런 것들은 해커들이 작정하고 공략하면 몽땅 크랙 되는 건 시간 문제일 뿐이었다.

그나마 인터넷이 발달한 게 소프트웨어의 복제와 배포뿐만 아니라 개발사에서 사용자의 접속 여부를 파악하는 것까지(= 정품 인증) 용이하게 만들어 줬으니 호재이다. 스타크래프트도 배틀넷에 접속할 때만은 CD key를 체크했듯이 말이다.

자동차는 철저하게 자기 소유 위주이고 운전만 면허이지만, 소프트웨어는 처음부터 소유라는 개념 없이 사용권이 허가되는 것이라고 여겨진다. 영어로는 똑같이 license라고 한다.
자동차는 물리적인 실물이 존재하고 조작하는 것이 매우 위험한 물건이지만, 소프트웨어는 실물이 없이 무한 복제가 가능하고 사용 자체에 위험성은 없는 물건이라는 차이가 있다. 형태가 서로 매우 극과 극이라 하겠다.

그래서 불가피한 상황에서 자동차 문을 따거나 배선을 뜯어고쳐서 키 없이 시동 거는 방법을 소개하는 동영상을 보면.. "남의 차에다가 이 짓을 하는 건 불법입니다. 반드시 자기 소유의 차에다가만 at your own risk로 시도하세요!"라는 주의 문구가 있다.

소프트웨어도.. 정품 사용자가 자기 개인 소장용으로만 복제판을 만들거나.. 혼자 쓰는데 번거로워서 정품 인증 절차를 없앤(..) 크랙을 돌리는 것은 내가 알기로 합법이다. 글쎄, 단순 복제판을 넘어서 후자는 엄밀하게 따지면 사용권 계약서에 명시된 "리버스 엔지니어링과 변조 금지"의 위반일 수 있겠지만 그것까지 현실적으로 다 따지고 잡아내고 법을 집행하는 건 거의 불가능에 가깝지 싶다.

소프트웨어의 라이선스는 대외 공개 여부, 유료/무료, 소스 공개 여부 같은 변수를 따져서 다음과 같은 범주로 나눌 수 있겠다.

2. 소프트웨어 라이선스의 등급

(1) 존재 자체가 영업 기밀: 개발사의 내부에서만 쓰이며, 돈을 아무리 많이 준다 해도 애초에 남에게 판매 자체를 하지 않는다. 주로 서버(호스트) 사이드 프로그램, 혹은 소프트웨어 개발을 위해 내부적으로만 쓰이는 아주 특수한 도구가 이 범주에 속한다. 이런 프로그램의 내부를 외부인이 구경하고 싶으면 아예 개발사를 통째로 사 버리고 인수해야 할 것이다.. >_<

(2) 상업용: 돈 받고 사용권을 판매하는 상업용 소프트웨어들. 옛날에는 제품을 디스크에 담고 패키지로 포장해서 일시불로 무기한· 영구적인 사용권을 제공했으나, 지금은 프로그램 자체는 웹사이트에서 받게 하고 사용권을 기간제로 찔끔찔끔 제공하는 형태가 대세이다. 얘부터는 소스 코드만이 영업 기밀이다.

(3) 무료 공개: 누구나 무료로 사용 가능하다. 하지만 제공된 형태 그대로 제품을 사용하는 것 말고 상업적 목적의 재배포, 변조 등등은 여전히 금지이다. 날개셋 한글 입력기는 이 등급이다.

(4) GPL 오픈소스: 단순히 무료 사용을 넘어서 소스까지 공개인 파격적인 제품이다. 하지만 저작권 자체가 아예 없는 건 아니며, 얘는 전염성, 즉 "오픈소스 덕을 봤으면 너도 오픈소스에 동참하라" +_+라는 이념이 담긴 등급이다. 그렇기 때문에 기업 영업 기밀에 속하는 소프트웨어에다 GPL 기반의 코드를 쓸 수는 없다.

(5) LGPL 오픈소스: GPL보다는 조건이 완화됐다. 요 등급은 상업용 제품에다가 끌어다 쓰더라도 자기 코드를 공개하지 않아도 된다. 요즘 많이 쓰이고 있는 MIT 라이선스도 이쪽 계열인 걸로 안다.
다만, 있는 그대로 쓰는 게 아니라 좀 변조해서 쓴다면 어떻게 바꿨는지 그 변조한 코드만은(자기 코드 말고) 공개하라는 식으로 바리에이션이 있다.

(6) public domain: 너무 오래돼서 저작권이 소멸됐거나, 저작권을 주장하는 주체 자체가 사라져서 존재하지 않거나, 아니면 이도 저도 아닌데 개발자가 너무 대인배여서 저작권을 주장하지 않고 "완전 니 마음대로 쓰셈"을 시전한 경우이다. SQLite처럼 드물게 public domain인 제품이 있다.

요 6등급 분류가 굉장히 깔끔하긴 하지만.. 현실에서는 이 범주에 딱 정확하게 떨어지지 않는 물건도 있다.

(1) 태생적인 반제품: 요즘은 소프트웨어라는 게 전반적으로 릴리스 후에도 끊임없이 보안 패치를 해야 하는 반제품 형태가 돼 있다. 하지만 그것 말고 미들웨어 라이브러리 같은 제품 중엔 유료로 판매되는 상업용이면서 아무 end-user에게나 판매하지 않고, 구매자에게 소스를 제공하는 형태가 있다.

(2) abandonware: 도스용/16비트용 프로그램들, 아래아한글 3.0/97, Windows 95/XP 따위.. 오늘날 아무도 실생활에서 사용하지 않는 옛날 구버전 소프트웨어들은 아무래도 상업적인 가치는 없다. 하지만 개발사에서 판매와 지원을 중단했다고 해서 그 프로그램의 저작권 자체가 법적으로 소실된 건 아니다. 저작권이야 거의 70년인가 그 동안 유지되기 때문이다. abandonware가 곧 public domain을 의미하지는 않는다.

그러니 한물 갔다고 해서 과거의 상업용 소프트웨어를 마음대로 불법복제 해서 써서는 안 된다. 개발사에서 정식으로 무료화를 선언하지 않은 한 말이다. 허나, 이제 더 정식으로 판매되지 않고, 돈 주고 사겠다고 해도 구할 수 없어서 복제해서 쓰는 걸 누가 어떻게 뭐라 하겠는가? 그런 구닥다리 제품으로 복돌이가 개인 단위로 무슨 금전적인 이익을 얻고 있을 리도 없고..
이런 이유로 인해 현실적으로는 개발사에서 저 정도는 사실상 그냥 방치· 묵인해 주고 있을 뿐이다.

3. 오픈소스

요즘 어지간히 규모 있는 소프트웨어에서 about 대화상자나 도움말의 한구석 acknowledgements란을 꺼내 보면.. 이 제품이 내부적으로 사용한 방대한 오픈소스 라이브러리 목록이 없는 경우를 찾기 어려울 것이다. 동영상이나 일반 데이터 압축, 암호화, 영상 처리, 폰트 렌더링, 심지어 머신러닝…

그 정도 규모와 기능이면 돈 받고 판매하는 미들웨어 솔루션으로 손색이 없을 텐데 이런 게 소스까지 공개로 죄다 풀리니 요즘 소프트웨어들은 기술 수준이 엄청나게 상향평준화될 수밖에 없다. 소프트웨어 업계는 자동차 같은 다른 업계에는 존재하지 않는 '오픈소스'라는 진영 내지 이념· 트렌드 때문에 판도가 굉장히 크게 바뀌었다.

이 진영이 없었으면, 혹은 오픈소스라 해도 몽땅 무식한 GPL 일색이어서 사실상 무용지물이었다면.. 컴퓨터에서 같은 기능을 사용하더라도 소비자는 더 비싼 제품을 써야 하고, 개발사는 여기 저기 로얄티를 내야 하는 게 많았을 것이다.

기능을 사용하는 것 자체는 몽땅 무료로 풀리게 됐으니.. 소프트웨어 업계는 그 사용자들이 무슨 기능을 즐겨 사용하고 무슨 생각과 취향을 갖고 있는지를 수집하고 분석하고.. 이걸로 "어떤 더 고차원적인 돈벌이를 할 수 있을까, 어떻게 하면 사용자의 취향을 더 정확하게 저격한 광고를 내보낼 수 있을까"를 고민하게 된 듯하다.

물론, 마소에서 개발한 소프트웨어에서 zlib나 FreeType, libPNG를 사용했네, MIT/LGPL 라이선스를 준수하네 이런 식의 acknowledgement를 볼 일은 지금까지 없었다. 걔네들은 오픈소스 진영과 동떨어진 채 타사에서 유료 구입하거나 자체 개발해 놓은 밑천이 워낙 많으니 어지간한 상황에 대해서는 그런 게 필요하지 않았던 것이다.

하지만 언제까지나 그렇게 지낼 수는 없을 것이고, 지금은 마소도 옛날 빌 게이츠/스티버 발머 시절처럼 오픈소스에 적대적인 독불장군이 절대 아니니 오픈소스 진영과 엮이는 비중이 차차 늘 것으로 보인다.

4. 소프트웨어 라이선스의 종류

이렇게 각종 소프트웨어들이 소스째로 무료로 풀렸다는 게 모든 지적 컨텐츠들이 풀려서 개나 소나 아무렇게나 사용해도 된다는 말은 결코 아니다. 오늘날 컴퓨터로 남이 만든 것을 활용해서 이를 바탕으로 또 뭔가 새로운 걸 만드는 일을 하는 사람이라면 그 어느 때보다도 저작권에 대한 인식을 분명히 하고 있어야 한다.

컴퓨터가 실행하는 코드의 집합체인 소프트웨어 프로그램뿐만 아니라 디지털 폰트, 그리고 하다못해 짤막한 4단짜리 찬양 악보나 노래 음원 하나라도 무료 사용이 허용되는 조건이 까다로워지는 것이 요즘 추세이다.

물론, 개인이 혼자 집에서 무료로 비영리 목적으로 사용하거나 보고 듣고 즐기는 것을 막는 저작권자는 사실상 없다. 음악, 특히 찬송 같은 건 알려져서 자기 곡이 어느 교회건 예배 때 회중 찬송으로 불리는 것을 싫어할 작곡자는 없을 것이다. 그러나 반대로 임의의 개작, 개조, 제작자 변조, 무단으로 상업적 활용 같은 걸 허용하는 저작권자는 이 세상에 존재하지 않는다.

운전 면허가 자가용과 사업용이 나뉘어 있듯, 소프트웨어의 사용권도 그런 형태로 나뉘는 경향이 있다.
폰트는 유료로 구매했다 하더라도 자기 개인 단위의 인쇄물이나 웹페이지에서만 사용할 수 있는 1차 라이선스, 더 나아가 옥외 간판이나 본격 상업 매체에 적용되는 2차 라이선스, 아예 제품에 범용적으로 포함되거나 특정 BI/CI에 들어가고 자기들만이 독점적으로 사용하는 전속 서체 급의 3차 라이선스 형태로 나뉘어진다.

반디소프트의 반디집의 경우 2020년 7.0 버전부터 유료 버전을 따로 내놓기 시작했는데, 파워 유저를 대상으로 하는 개인 단위 유료(프로) 에디션, 그리고 기업에서의 사용을 염두에 둔 PC 단위 유료(엔터프라이즈) 에디션을 내놓은 게 무척 독특하다. 현실성 있는 유료화 정책에 대해 개발사에서 고민을 많이 한 것 같다.

엔터프라이즈 에디션을 구매하지 않은 기업 내부라고 해도 각 직원이 무료 에디션은 여전히 사용할 수 있다. 그 대신 얘는 광고가 뜨며, 기업 서버와의 최소한의 접촉을 막을 수 없다(업데이트 체크, 언제나 온라인으로만 설치).

이런 라이선스 종류는 아까 같은 영업기밀~소스 공개 같은 수직 비교와는 다른 양상의 수평 비교라고 볼 수 있을 듯하다.

Posted by 사무엘

2020/03/12 08:35 2020/03/12 08:35
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1727

1. 동영상

유튜브가 광고 없는 유료 프리미엄 서비스를 밀고 홍보하기 시작하더니, 2019년 하반기쯤부터는 반대로 일반 무료 상태에서는 광고가 예전보다 더 길어지고 잦아진 것을 다들 느끼실 것이다. 원래 5초 1회로 시작했던 것이 6~7초 2회로 늘었다. 요런 걸로 유료 가입자를 확보하고 수익을 내려는가 보다.

하긴, 유튜브는 인터넷에서 깨진 동영상 링크라는 걸 없애고, 오프라인 다운로드가 당연하다고 여겨졌던 60프레임 HD급 초고화질 동영상까지 실시간 스트리밍으로 실현한 엄청난 사이트이다. 모니터 주사율만 해도 평소에 50~60Hz를 쓰다가 75Hz이상을 맞추면 화면이 훨씬 더 부드러워진 게 느껴지는데.. 동영상도 60프레임짜리를 보면 화질을 떠나서 움직임이 확~ 더 자연스럽고 부드럽고 보기 편한 게 티가 난다.

쟤는 그냥 지구상에 존재하는 모든 영상 기록들의 아카이브인 동시에 전세계의 개인 방송, 교회 설교 같은 것까지 몽땅 감당하고 있다. 집에 TV가 없어도 유튜브가 TV나 마찬가지이다. 동영상을 하나 보기 시작했다가 같이 뜨는 관련 동영상까지 섭렵하다 보면 시간 가는 줄 모른다.

이런 괴물이 등장할 거라고는 198, 90년대의 그 어떤 SF 작가도 예상하지 못했으며..
저걸 돌리려면 평소에 서버 유지비도 정말 장난 아니게 들지 싶다.;;; 이걸 버틸 재간이 안 되는 국내의 중소 동영상 포털들은 수지가 안 맞으니 2010년대 초· 중반을 못 넘기고 다들 망했다.

한 20여 년 전에 컴퓨터에서 동영상이라는 건 그냥 320*240의 자그마한 화면에서 노이즈 대신 JPG artifact가 가득한 허접한 화질로 보는 avi, mpg, mov가 전부였다. 전반적인 화질은 기존 VHS 비디오 테이프보다 결코 좋을 게 없고, 단지 아날로그가 아닌 디지털이라는 의의만 있을 뿐이었다.
1990년대 초-중까지는 MPEG1/2급 동영상을 시청하기 위해서 별도의 그래픽 가속 하드웨어를 장착해야 할 정도였다. 동영상 캡처/인코딩이 아니라 단순 시청을 위해서도 말이다. 이런 가속은 통상적인 3D 그래픽용 가속과는 별개의 분야일 것이다.

그러다가 한 2000년경엔 갑자기 온갖 코덱들이 난립하기 시작해서 통합 코덱 패키지가 나오고, '사사미'라고 자막이 화면에 깔끔하게 입혀진 채로 뜨는 새끈한 동영상 재생기가 개발되었다. 이때까지만 해도 고화질 영화· 애니 동영상은 각종 P2P 불법 공유 네트워크를 통해 많이 오갔던 것 같다.
온라인 실시간 스트리밍으로는 어림도 없고.. 유튜브만 해도 2010년대 이전에는 여전히 3~400대 해상도에 머물러 있었으며 동영상 하나당 10분 시간 제한까지 있었다. 지금으로서는 믿어지지 않을 것이다.

난 동영상 압축 알고리즘에 대해서는 아는 게 별로 없다. 인접한 프레임, 그리고 인접한 픽셀들이 서로 유사하다는 것을 이용해서 차이점만 담는다는 것이 골자일 텐데.. 이건 컴퓨터에서 캐시의 개념을 설명할 때 언급하는 시간 지역성, 공간 지역성하고 비슷한 개념 같다. 그나마 동영상 재생 및 압축 기술이 다들 대인배 오픈소스로 풀려 있기 때문에 사람들이 폰이나 PC에서 더 저렴하고 간편하게 동영상을 즐길 수 있다.

2. CPU의 다양다변화, 병렬화

21세기에 컴퓨터 CPU에서 단일 코어 클럭 속도의 '기하급수' 증가가 드디어 멈췄다. 그 대신 지금까지 슈퍼컴퓨터 세계의 전유물로 여겨졌던 멀티코어가 개인용 PC에도 등장하게 됐다. 이게 1차 변화이다.

그래서 어느 플랫폼에서나 동일한 방식으로 스레드를 생성하라고, CPU의 여러 코어를 잘 제어하고 활용하라고 OpenMP라는 규격이 제정되기도 했다. 이건 특정 연산에 대해서 적당히 병렬화하라고 지시를 내리는 여러 C 함수와 언어 확장, #pragma들의 모음이다. 난 지금까지 UI의 반응성 향상을 위해서만(= 백그라운드 작업) 스레드를 사용해 왔지, CPU 자원을 몽땅 쪽쪽 빨아서 쓰기 위해서 스레드를 동원해 본 적은 없었다.

요즘 컴퓨터들은 뺑뺑이를 돌려 봤자 전체 CPU 사용량이 10%대밖에 되지 않는 건 사실이다. 하지만 그렇다고 해서 별다른 최적화 없이 무턱대로 스레드를 만들어서 CPU 사용량을 늘리면 그래 봤자 throughput이 그저 전체 CPU 사용량에 비례해서 팍팍 오르는 것은 확실히 아니어 보인다.

작업 스레드를 만들면 각 작업들의 수행 속도도 눈에 띄게 느려지기 때문이다. 이는 어지간한 하이엔드급 컴에서도 관찰 가능한 현상이다. 뭐랄까, 작업 스레드가 증가하면 context switching 같은 다른 오버헤드도 추가되어서 전체 효율이 떨어지는 것 같다.

프로그램을 너무 많이 띄워서 메모리가 부족해지면 가상 메모리 페이징(디스크 스와핑)만 죽어라고 하느라 컴퓨터의 작업 수행 속도가 급락한다. 좁은 화면에 창을 너무 많이 띄우면 사람도 창 전환만 하느라 작업 능률이 급락하며, 반대로 모니터를 여러 개 연결하는 건 생산성을 사기급으로 향상시킨다.
이와 마찬가지로 CPU의 성능에 걸맞지 않게 작업 스레드가 너무 많아지만.. 작업 전환 비용의 증가만으로 성능이 극도로 떨어질 수 있겠다.

그런데 요즘은 그걸로 끝이 아니다. 게임용 3D 그래픽 렌더링이나 좀 보조하라고 만들어졌던 add-on인 GPU도 거기에만 쓰는 게 아깝다. 굳이 3D 그래픽이 아니어도 그것처럼 단순무식하고 물량빨인 계산 작업이 있으면 거기에도 GPU를 투입할 수 있다. 특히 살인적인 노가다 계산이 필요한 머신러닝 분야에서 GPU 연산이 더욱 각광받기 시작했다.

그러니 이것도 별도의 프로그래밍 영역이 됐다. nVIDIA에서 GPU 활용 프로그래밍을 위해 OpenMP와 비슷한 컨셉으로 CUDA라는 라이브러리를 내놓았다. 이건 그냥 인텔 내장 그래픽을 쓰는 노트북 같은 기계에서는 활용할 수 없다는 것이 멀티코어 CPU와 다른 점이다. 그것 말고 OpenCL 같은 다른 GPU 라이브러리도 등장했다.

하긴, 아직 싱글코어 시절일 때도 아까 얘기했던 동영상 정도의 멀티미디어 처리를 위해서 인텔에서는 SIMD(1명령 다중 데이터) 정도의 병렬 처리를 지원하는 명령을 도입한 적이 있었다. 그게 옛날 1990년대 말의 펜티엄 프로~III 기간에 추가된 MMX 내지 SSE 명령이다. 얘가 기존 x87 명령을 대신해서 부동소수점 연산까지 처리한다.

옛날에 하드웨어의 성능을 극한으로 짜내는 게임을 만들려면 어셈블리어를 알아야 하고 비디오 메모리에 직통으로 내용을 직접 뿌린다거나 해야 했다. 지금은 특정 CPU의 인스트럭션을 써 주는 짓은 필요 없지만, 그것과는 좀 다른 양상으로 하드웨어를 직접 다루는 최적화 테크닉이 필요한 시대가 되어 있다.

3. 슈퍼컴퓨터 내지 CPU 아키텍처의 명멸

본인은 어린 시절에 슈퍼컴퓨터라고 하면 덩치가 크고, 내부에 무슨 금칠이라도 했는지 가격이 억소리 나게 비싸면서.. 개인용 PC보다 메모리가 훨씬 더 방대하고 반응 속도가 수십 수백 배 정도 더 빠른 물건 정도로나 생각했다.
뭐, 20세기 옛날에는 개인용 컴퓨터 대비 전용 슈퍼컴의 차이가 그런 단순한 차이점에 더 근접해 있기도 했다.

하지만 오늘날은 개인용 PC가 10~20년 전의 업계 최고의 슈퍼컴보다 더 빠르다. 마치 오늘날의 무선 인터넷이 10~20년 전의 유선 인터넷보다 더 빠르듯이.. 정말 경이로운 노릇이다.
이제 슈퍼컴이라고 해서 개인용 PC보다 단순히 기계적으로 무식하게 더 빠르지는 않다. "개인용 PC가 64비트 3~4GHz대니까 슈퍼컴은 machine word가 256비트이고 클럭 속도는 40GHz 정도 하겠지"가 아니라는 뜻이다.

이제는 슈퍼컴 전용 아키텍처, 전용 운영체제 같은 것도 존재하지 않으며, 비트 수가 차이 나는 것도 아니고.. 다 똑같이 x86이다.
차이가 나는 건 계산을 위한 코어수뿐이다. 그걸 정교하게 제어하는 별도의 프로그램을 짜서 돌려야 슈퍼컴의 성능을 제대로 활용할 수 있다.

단일 코어의 클럭 속도는 이제 개인 PC도 슈퍼컴과 비슷하거나 더 나으면 낫지, 결코 뒤쳐지지 않는다.
그냥 단일 코어만 열나게 돌리는 PC용 PI 계산 프로그램을 그대로 돌리면 슈퍼컴이라고 해서 몇백만 자리가 즉시 짠~ 하고 튀어나오지 않는다.

옛날의 전용 패러다임과 재래식 생산 공정 하에서 슈퍼컴을 열심히 연구 개발했던 크레이 같은 공돌이가 오늘날의 컴퓨팅 환경을 본다면 놀라서 까무러치지 않을까 싶다.
통상적인 시뮬레이션· 계산용 슈퍼컴은.. 단순히 외부로부터의 대용량 트래픽 처리용인 고성능 서버하고는 지향하는 게 다르다. 스포츠 사격과 군대 사격이 다른 것만큼이나 다르다고 생각하면 될 듯하다. IBM 메인프레임은 둘 중 어느 용도에 더 가까운 걸까..?

오늘날은 PC가 성능이 워낙 향상되어서 PC와 슈퍼컴 사이의 경계 축에 들던 '워크스테이션'이라는 컴퓨터 체급도 의미가 많이 퇴색했다. 굳이 따지자면 맥 프로 같은 high-end급 PC일 뿐이겠지.
그 시절에 워크스테이션이란 운영체제도 OS/2나 솔라리스, NextStep, Windows NT 정도 돌리던 전문가 업무용 컴터였으며 가격은 거의 경차 한 대에 육박했었다. 노는 물이 도스나 Windows 3.1 따위하고는 완전히 달랐다.

이런 식으로.. 데스크톱 PC는 호환성이 깡패인 x86+x64 천지가 됐고, 모바일은 ARM인데 얘들도 PC로 호시탐탐 진출하려고 노력하는 중.. 거기에다 게임기는 아직 PowerPC가 살아 있나 모르겠고, 메인프레임에 IBM POWER 정도가 살아 있는 것 같다.
이젠 구글과 애플도 CPU를 직접 만들려고 하고.. 과거 Windows NT 3~4 시절과는 다른 의미의 CPU 아키텍처 춘추 전국 시대가 열리는 게 아닌가 모르겠다. 결국은 이식성 좋게 만들어진 소프트웨어가 승자가 된다.

4. 전자와 전산의 관계

가만히 생각해 보면.. C++ 언어로 Windows MFC 등.. 상대적으로 '특정 플랫폼 실무에 가까운 프로그래밍'을 자주 하는 사람은 전산· 컴공보다는 전자공학 쪽에 더 많았던 것 같다. 과거에 유명한 Visual C++ 프로그래밍 베스트셀러 책을 집필했던 분들도 전공이 그런 쪽이었다. 세부적으로는 로봇 공학이라든가 디지털 신호 처리 쪽으로 말이다.

그럼 진짜 전산· 컴공을 한 사람들은 뭘 하는가 하면.. 좀 더 크로스 플랫폼이나 오픈소스에 친화된 스타일의 코딩을 한다. 뭐, 웹 프로그래밍도 방법론은 사뭇 다르지만 크로스 플랫폼 프로그래밍의 범주에 들 테고..
특히 PL 쪽 덕후들은 C++ 같은 지저분한(?) 언어는 거들떠보지도 않고 Rust나 go 같은 더 마이너한 언어, 함수형 언어 같은 걸 즐겨 쓴다. 쉽게 말해 더 추상적이고 고차원적인(?) 걸 추구하는 듯하다.

아 그렇다고 모든 전자과 출신이나 모든 전산과 출신이 취향이 그렇게 갈린다는 말은 물론 아니다.
그리고 신호 처리는 전자공학이지만 컴퓨터그래픽스는 명백하게 전산학의 세부 분야인 것 같다. 요컨대 영상을 렌더링 하는 건 전산학이고, 그 생성된 영상을 손실 압축해서 저장하는 건 전자공학 쪽인 셈이다. 다음으로 영상 인식 같은 건 전자와 전산이 별 구분 없이 같이 파는 것 같다.

Posted by 사무엘

2020/02/16 08:36 2020/02/16 08:36
,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1717

1.
작년 말(12월)부터 국내에서는 잘 알다시피 5G 이동통신 기술이 상용화 됐다. 그런데 그런 뉴스가 전해지기 전부터 언제부턴가 집과 각종 공공장소의 와이파이 접속명은 뒤에 5G가 붙기 시작해서 iptime5G 이런 식으로 바뀌었고, 속도도 더 빨라지긴 했다.
똑같은 전자기파와 똑같은 랜선을 쓰면서 어떻게 인터넷 속도가 이렇게 계속 더 빨라질 수 있는지 신기할 따름이다. 컴퓨터 클럭 속도는 멈춘 지 15년 가까이 됐지만, 현재까지 아직도 치트키 수준으로 경이롭게 증가하고 있는 건 인터넷 속도인 것 같다.

2.
컴퓨터 키보드의 글쇠들 주변을 보면, 다른 먼지들이 쌓여서 더러워지는 건 이해가 되는데 1~2cm 남짓한 길이의 솜털들은 도대체 어디서 떨어진 건지 모르겠다.
손가락 끝이나 손바닥서 털이 나는 것도 아니고, 사람 얼굴에서 떨어진 털이 거기로 갈 리는 없을 텐데.. 알 수 없는 노릇이다.

3.
옛날에 비해 컴퓨터 장치들이 독립성이 강화되고 더 똑똑해지는 게 느껴진다.
가령, 옛날에 모니터와 이어폰은 전통적으로 자신만의 전용 단자가 있으며(직렬· 병렬 포트나 USB 따위가 아닌), 컴퓨터의 입장에서는 꽂든지 말든지 소프트웨어적으로 별 차이나 반응이 없던 물건이었다.

그러던 것이 언제부턴가 컴퓨터에서 각 모니터의 탈착을 감지할 뿐만 아니라 그 모니터의 종류, 적정 해상도와 주사율까지 알아서 조절하게 됐다. 그리고 사운드 쪽도 이어폰을 꽂은 상태에서 볼륨을 너무 높이면 컴퓨터가 사용자의 청력까지 걱정해 주는 경지에 다다랐다.

옛날 브라운관 모니터는 밝기 조절, 채도 조절, 상하좌우 shift/resize를 전부 별도의 다이얼을 돌려서 해야 했다. 그러나 요즘 모니터는 자체적으로 컴퓨터 프로그램 UI가 내장되어 있기 때문에 메뉴와 화살표, 엔터 같은 키만 있다.
아울러, 노트북의 터치패드도 단순히 마우스와 호환되는 포인팅 장비가 아니라 자체적인 옵션을 갖고 있고(각종 제스처 인식 여부) 드라이버를 잡아 줘야 하는 물건으로 탈바꿈했다.

4.
본인이 회사에서 사용하는 컴퓨터는 CPU, 그래픽 카드, 메모리 등 하드웨어 전반이 전형적인 2010년대 중반급의 사양이고 별다른 이상이 없다. 그런데 화면의 반응이 왠지 굼뜨고 느리게 느껴져서 불편했다. 간단히 창을 마우스로 끌어서 이동시켜 봐도 모션이 매끄럽지 않고 미묘하게 랙이 걸려서 뚝뚝 끊기는 것 같았다.

듀얼 모니터 중 하나가 4K급 해상도여서 혹시 비디오/디스플레이 쪽으로 성능이 딸리는 병목이 존재하나 의문이 들었는데.. 그 예상이 반은 맞고 반은 틀렸다. 그쪽 문제인 건 맞지만 원인이 컴퓨터 쪽이 아닌 모니터에 있었기 때문이다.
모니터가 4K 해상도에서는 주사율이 30hz밖에 되지 않았던 것이다.

옛날에는 그냥 평범한 모니터가 보통 50hz이고, 좀 좋은 제품은 60내지 그 이상이었던 것 같다. 주사율이 높으면 마우스 포인터의 이동 모습이 아주 부드러워져서 컴퓨터를 쓰는 인상, 경험, 느낌을 좋게 하는 데 큰 기여를 했다.
또한, 유튜브 동영상만 해도 단순히 화질만 720~1080 HD급이 아니라 프레임 수도 60fps라고 기재된 게 있다. 그건 타 동영상에 비해 모션이 아주 자연스럽고 부드러운 게 티가 나며, 감상할 때 심리적으로 굉장히 긍정적인 느낌을 준다.

그런데 모니터에서 초고해상도를 구현하기 위해서 이런 중요한 주사율을 등가교환하다니...;; 컴퓨터가 성능이 아무리 좋아서 화면을 초당 수백 회 고치더라도 사람은 모니터 주사율보다 더 부드러운 화면을 볼 수 없게 된다.
LCD는 과거의 브라운관 CRT보다는 주사율이 낮아도 괜찮다고 하지만 그래도 그렇지 30hz는 너무 심한 것 같다.

과거에 영화라는 게 처음 발명됐을 때의 기본 프레임 수인 24fps는 30보다도 작은데, 사람이 끊김 없이 자연스러운 영상이라고 느끼는 가히 최소의 마지노 선으로 잡은 값이라고 한다. 이 숫자를 정하기 위해 인지과학적인 실험과 고찰이 들어갔지 싶다.
아날로그 텔레비전의 주사율은 교류 전기의 진동 주기와도 연계해서 설정되었다고 한다. 60hz이면 그와 연계해서 30hz (= 30fps) 같은 식이다. 물론 디지털 동영상에서 프레임 수나 최신 디스플레이에서 주사율은 굳이 그런 것에 얽매이지 않고 그냥 정하기 나름이고 기계의 제조 원가나 전력 소모 대비 기술적 한계에 달려 있다.

일반 정지 영상에서 여러 안티앨리어싱 기법이 존재하듯, 영상에서도 motion blur라고 그야말로 애니메이션계의 안티앨리어싱에 해당하는 기법이 있다. 낮은 fps에서도 동영상이 뚝뚝 귾기지 않고 최대한 부드럽게 이어지듯 보이게 하기 위해서이다. 3D CG로 동영상을 생성하는 그래픽 소프트웨어 내지 각 프레임들을 이어서 동영상을 만드는 인코더가 그런 것까지 감안해서 넣어 주는 기능이 있을 것이다.

말이 나왔으니 말인데, 화면의 해상도와 프레임 수뿐만 아니라 종횡비 그 자체도 어쩌다가 지금처럼 바뀐 걸까? 어쩌다 보니 컴퓨터용 모니터는 가로로 더 길쭉해졌고 스마트폰은 세로로 더 길쭉해졌을까? 모든 영화들은 종횡비가 동일한 걸까? 이런 것도 알고 보면 내력과 사연이 많이 있는데 기회가 되면 차츰 더 알고 싶다.

5.
SSD는 뭐랄까.. 양날의 검 같다.
기계적인 동작이 없으니 소음 없고 전력 소모 적고, 엄청 빠르고.. 비싼 것만 빼면 하드디스크를 완전히 압도하여 조만간 주기억장치와 보조 기억장치의 경계를 허물 것 같은 신기술임이 틀림없다. 반도체 공학의 신비로움을 다시 생각하게 된다.

반도체 기반 보조 기억 장치들은 외형과 단자 형태에 따라 (1) USB 메모리 스틱, (2) SD 카드, 또는 (3) SSD로 나뉘는 듯하다. 그 중 SSD는 광학 디스크(CD/DVD)나 USB/SD와 달리, 하드처럼 같은 C: 고정식 디스크 역할을 한다는 특징이 있다. 동작 원리는 기계식 하드와 완전히 다르지만 말이다.

그러니 하드/SSD만 일컫는 통합 명칭이 필요해 보인다. 고정 디스크? 하드라는 명칭이 너무 굳어졌다면 '기계식 하드/SSD 하드'라는 말이라도 쓰여야 할 것 같다.
그리고 어떤 로컬 디스크에 대해서 파일 시스템이야 요즘은 Windows 기준으로 NTFS가 아닌 곳이 없을 테니 별 의미가 없고.. 디스크가 기계식 하드인지 SSD인지를 되돌리는 API도 GetVolumeInformation 같은 급의 함수에 있어야 하지 않나 생각이 든다.

그런데 자동차가 엔진 제어 방식이 기계식에서 전자식으로 바뀌면서 원인 불명의 급발진이 발생하기 시작한 것처럼.. 디스크 역시 기계식에서 전자식으로 바뀌면서 일상적으로 편리해진 대신에 뭔가 안정성이 떨어진 것이 있다. 단순 가격 차이를 떠나서 SSD는 기계식 하드를 완전히 대체하기에는 아직 5% 부족한 면모가 있다. 이 사이트의 글을 한번 읽어보자. "화 있을진저, 너희 백업 없이 SSD를 쓰는 족속들아!"

  • SSD는 한번 고장 나면 데이터를 살릴 가능성이 거의 없는 매체이다.
  • 하드가 충격이나 자성에 약하다면 SSD는 열과 전기 충격에 매우 약하다. (불안정한 전류, 갑작스러운 정전, 컴퓨터 다운, 과열..) 취약한 분야가 서로 다름.
  • 하드는 배드 섹터를 빼고 나머지 부분이라도 읽고 복구가 가능하지만 SSD는 그런 것 없다.

하긴, 정전이 돼서 작업 중인 데이터를 날렸다고 해서 자기 컴의 RAM의 복구를 시도하는 건 불가능할 것이다. 물론 SSD는 RAM과 같은 구조의 기억장치는 아니지만 SSD도 그만치 훅 가기 쉽다는 뜻이다.

본인도 새로 산 노트북을 사용한 지 불과 5개월 남짓 만에 SSD 불량으로 인한 교환을 경험했기 때문에 이 경고가 더욱 공감이 갔다. 심각한 피해를 입은 정도까지는 아니지만 그래도 꼼꼼히 백업하지 않던 기록과 소스 코드를 일부 날렸기 때문이다.
하드디스크는 떨어뜨리고 물에 집어넣은 것도 국가 수사 기관 차원에서 작정하고 털면 무슨 끈질긴 생명체마냥 내용을 어느 정도 복구해 낸다고 한다. 하지만 SSD는 정말로 훅 가기 때문에 이거 뭐 정보 보호와 보안 관점에서는 더 편리할지도 모르겠다..;;

옛날에는 노트북에서 자주 발생하던 잔고장이 액정 화면의 접촉 불량, 그리고 키캡 이탈이었는데.. 2010년대에 구매한 제품에서는 그런 건 없고 하드와 SSD의 접촉 불량을 더 자주 겪었다. 그러고 보니 운영체제를 재설치하는 통과의례도 Vista 시절부터는 없어졌다. 자동차고 컴퓨터고 모두 지난 20여 년 동안 참 많이 바뀐 것 같다.

Posted by 사무엘

2019/08/18 19:35 2019/08/18 19:35
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1652

인간이라는 존재에 대한 생각

1. 컴퓨터와 인간

전에도 한번 이야기한 적이 있지 싶은데..
컴퓨터는 전원을 넣은 뒤에 실제로 사용 가능해질 때까지 준비 시간이 대단히, 가장 긴 전자 기기에 속한다.
디지털 카메라와 스마트폰, 컴퓨터와 단순 계산기를 비교해 봐도 차이를 알 수 있다.

그 이유는 컴퓨터에는 '부팅'이라는 절차가 필요하기 때문이다. 요즘은 하드디스크 대신 SSD 덕분에 부팅 속도가 굉장히 빨라지긴 했지만, 컴퓨터가 사용 가능해질 때까지 내부적으로 무수히 많은 준비 작업을 해야 한다는 사실은 변하지 않는다.

왜 그런 걸까??
범용 컴퓨터는 타 전자 기기들과는 차원이 다를 정도로, 넘사벽급으로 확장과 프로그래밍 활용도가 높기 때문이다. 기본적으로, 선천적으로 할 줄 아는 건 없다시피하고 프로그램만을 기막히게 빨리 잘 수행한다.

그렇기 때문에 컴퓨터는 정말 하나부터 열까지, 다른 전자 기기라면 회로 하드웨어 차원에서 콕콕 박혀 있을 명령과 데이터도 다 일일이 매번 메모리에다 새로 주입해 줘야 하며, 자신과 일체형이 아닌 타 하드웨어들을 감지하고 초기화하고 점검해 줘야 한다. 오늘날의 컴퓨터가 괜히 '프로그램 내장형'인 게 아니며(메모리에 내장), 그러니 이런 오버헤드가 클 수밖에 없다.

컴퓨터와 단순 비교는 안 되겠지만, 인간만 해도 직립보행과 큰 두뇌를 얻기 위해 타 동물들에 비해 생물학적으로 다른 장점을 희생한 게 많다고 한다. 태어난 직후엔 다른 어떤 동물의 새끼보다도 무능하고 연약한 상태이며, 다른 어떤 동물보다도 엄마 품에 오래 있어야 한다. 비슷한 덩치의 다른 동물에 비해 힘이 약하고 소화 효율도 그리 좋지 않다.

하지만 그 연약한 인간은 동물이 상상도 할 수 없고 신묘막측의 영역에 가까운 언어 습득과 구사 능력이 있으며, 창의적인 생각을 할 수 있다. 불을 다루는 능력도 지구상에서 인간 외에 다른 어떤 생명체도 갖추고 있지 않다. 인간이 아닌 다른 동물이 스스로 불을 피운다거나 돌멩이를 집어서 던질 줄 안다면 그것만으로도 충공깽일 것이다. (뭐, 그래 봤자 인간에게 제압당하는 건 변함없겠지만, 그와는 별개로)

컴퓨터가 타 전자 기기들과 구조적으로 다른 것만큼이나 인간도 다른 포유류와 구조적으로 다른 것이 있다. 둘이 서로 같지는 않아도 비슷한 양상이긴 해 보인다.

2. 정치와 종교 싸움

인간이 나누는 여러 대화 주제들 중에 정치와 종교는 제일 골치 아프고 답 안 나오며 사람을 친구 아니면 적으로 극단적으로 가르는 분야이다. 사람들이 기를 쓰고 자존심을 걸고서 자기 신념을 고집하는 분야이다. 그러니 어지간해서는 이런 주제는 안 꺼내는 게 좋다.

그럼에도 불구하고 인간은 이 분야에 어느 정도는 관심을 갖지 않을 수 없다. 인간은 그저 먹고 자고 싸고 씨 뿌리는 욕망만 충족되면 되는 개돼지 짐승이 아니며, 그보다 훨씬 더 고차원적인 가치를 추구할 줄 알기 때문이다. 게다가 크리스천에게는 종교관 한정으로 복음 전파의 의무도 있다.

둘 중 정치는 내가 속한 "집단의 현재 현실" 또는 가까운 미래와 관계가 있다. 내가 낸 세금을 정치인들이 내가 원하는 방식대로 쓰지 않고 사회와 국가· 민족 전체를 공멸로 몰고 가고 있다면, 이에 대해 분노하고 항거하는 것이 개인의 권리이자 어느 정도 의무이기도 하다. 정치인들이 뻘짓 한 게 당장 나에게까지 돌아와서 해를 끼치기 때문이다.

그 반면, 종교는 "개인의 가치관(특히 경전의 해석 체계) 내지 영원", 먼 미래(특히 죽음 이후)와 관계가 있다. 현실 그 자체인 정치와 달리 추상적이고 비가시적이고 형이상학적인 분야에 대한 신념을 다루며, 스케일도 집단이 아니라 개인으로 줄어든다.

정상적인 정교 분리 국가라면, 주변에 온통 자신과 종교관이 다른 사람뿐이라고 해도 세금이 낭비된다거나 국가 안보가 무너진다거나 하지는 않을 텐데.. 그래도 이게 다르면 사람간에 어느 수준 이상으로는 더 가까워질 수 없어진다. 특히 이것 때문에 결혼도 못 하고 파토 난다.
이렇듯, "집단의 물질적인 현재"와 "개인의 영적인 미래"를 다루는 두 축은 인간의 자아 및 정체성과 밀접한 관계가 있다.

내 개인적으로는 동일한 분별력과 믿음과 양심이라면 정치 성향과 종교관도 뭔가 일관되게 동일하게 나오지 않겠나 생각하지만.. 현실에서는 본인과 신앙관이 일치하고 정치 성향만 정반대인 사람, 혹은 반대로 정치 성향만 일치하고 종교 쪽은 정반대인 사람도 많이 봐 왔다. 글쎄, 어떤 건 취향 존중의 영역이겠지만.. 명백하게 옳고 그름의 영역인 것까지 좌우 균형 취향으로 왜곡되는 일은 없었으면 좋겠다.

3. 인종간의 우열?

제임스 왓슨과 프랜시스 크릭이라고.. 20세기 중반에 DNA의 이중나선 구조를 발견한 엄청난 생물학자가 있다. 이과 출신이라면 다들 이름을 기억하실 것이다. 크릭은 2004년에 사망했지만 왓슨은 90대의 나이로 현재까지 살아 있다. (과거 vs 현재)

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

이 두 사람은 획기적인 연구 성과 덕분에 노벨 상을 받고 엄청난 부와 명성을 얻었으나.. 나중엔 무슨 마가 꼈는지 유전자 차원에서의 인종의 우열 운운하는 또라이 같은 망언도 많이 늘어놓고 소신을 굽히지 않았다. 이 때문에 늘그막의 이미지를 많이 구겼다.
인텔의 창업주인 누구누구가 엔지니어로서는 아주 뛰어난 사람이었지만 노조를 탄압한 악덕 기업주였네 뭐네 하는 소리처럼 들리는데.. 저 사람들은 기업가가 아닌 학자였고, 단순히 돈만 밝힌 것하고는 흑역사가 차원이 달랐다.

타 분야의 전문가가 자기 전공과 무관한 정치· 종교· 이념 쪽으로 어그로를 끄는 것도 아니고, 유전자 쪽 연구의 넘사벽급 전문가가 직접 그런 식으로 얘기를 하니 논란은 더 커질 수밖에 없었다.
"백인과 흑인이 동등한 지적 능력을 갖췄다는 것은 사실이 아니다. 흑인 직원을 다뤄 본 사람이라면 내 말에 다들 공감할 거다." / "인종 간 지능의 우열을 가리는 유전자가 앞으로 10년 안에 발견될 수 있을 것" ... ㅡ,.ㅡ;;

이 때문에 왓슨은 국제 왕따로 전락해서 강연 초청과 책 출판 계약이 몽땅 짤리고.. 한때는 생계를 위해 노벨 상 메달을 경매에 내놓기까지 했을 정도로 몰락했다고 한다.
학자가 논문 표절, 연구 결과 조작, 연구비 횡령, 마루타 실험-_- 같은 업무상의 비윤리적인 짓 때문이 아니라, 개인적인 사상과 신념이라는 외부 요인만으로 학계에서 매장 당하기란 참 쉽지 않을 텐데.. 저 사람은 그 어려운 일을 해냈다.

안 그래도 진화생물학 진영에서는 진화론은 우생학과 아무 관계 없다고 못을 박으며, 기독교 창조론자들이 벌이는 진화론 비방(?)과 음해를 굉장히 싫어하는 편이다. 하지만 왓슨과 크릭의 언행은 진화론이 동일선상에서 비방 받을 빌미를 잔뜩 제공하게 됐다. 물론 교인들도 밖에서 개독 소리 들을 짓, 예수 이름이 모독 받을 짓을 한 게 많으니 서로 상쇄되는 건가.. -_-;;;

이 점을 감안하여 본인은 거리 설교를 하면서 기원에 대해 잠깐 언급할 때, 진화론을 대놓고 공격하고 욕하지 않는다. 단지, 우주와 생명이 다 우연히 저절로 생겨났다고 믿는 게 신이 창조했다고 믿는 것보다 더 큰 믿음이 필요하다고만 말한다.

난 왓슨 저 양반이 무슨 말을 하고자 하는지 취지는 얼추 알 것 같다. 백인들이 탁월한 과학 기술로 세계를 정복했으며, 나머지 나라 사람들은 미개했던 게 사실이다.
하지만 그렇다고 그런 말을 저렇게 공공연하게 할 필요는 없다. 차라리 저 사람이 비정상적인 PC(정치적 올바름) 트렌드를 저격하면서 "결혼이란 남자와 여자가 하는 것이고 동성애는 잘못됐다, 빨갱이는 박멸해야 된다" 같은 식으로 과격한 말을 한 거라면 성경적으로 실드 받을 여지라도 있을 텐데.. 저건 아무 실드 없이 자기 무덤을 파는 짓일 뿐이다.

인종 간에 유전자 차원에서 지능의 우열이 정말 있을 수는 있다고 치자.
평균 이상으로 천재 괴수들을 줄줄이 배출한 가문이 있다면 저 사람들은 유전자 차원에서 뭐가 있는지 궁금해질 법도 하다. 실험 결과가 참 불편하게 느껴지겠지만 그걸 과학적인 방법론으로 객관적으로 규명할 수만 있다면 과학자의 연구 대상이 될 수는 있을 것이다.

그런데 그런 연구가 정치 개입 없이 객관적으로 제대로 진행되기란 현실적으로 매우 어려우며, 그건 십중팔구 "열등한 인종은 없애 버려야 된다, 고자로 만들어서 대를 끊어야 된다" 같은 나치즘 내지 다윈 상을 암시하는 결론으로 곡해되기 쉽다. 그렇기 때문에 그런 생각을.. 혼자만 하고 마는 것도 아니고 공공연하게 표현까지 하는 건 미친 짓 위험한 짓이라는 소리가 나오는 것이지 싶다.

난 개인적으로는 인종뿐만 아니라 언어조차도 어떤 의미에서는 우열이 존재한다고 생각한다. 로마 숫자와 아라비아 숫자가 우열이 존재하는 것만큼이나 말이다.
어떤 언어는 다른 언어보다 더 오버헤드 적고 간결하고, 학문이나 기계화나 성경 번역 같은 용도에 구조적으로 더 유리하다고 생각한다. 어휘, 문법, 문자 표기 등등을 총체적으로 따져 봤을 때 말이다. 선천적인 요소와 후천적인 요소의 비율까지는 차마 단정적으로 말하지 않겠다.

하지만 그런 견해를 피력한다고 해서 상황이 달라질 것은 없고, 열등한 언어를 쓰는 사람은 머리를 개조해서 모국어를 강제로 바꾼다거나 나가 죽어야 하는 것도 아니다. 총체적인 검증과 비교가 가능하지 않으니 이런 생각은 혼자만의 심증 수준에 머무를 뿐이다.

오늘날 언어학 전공자들은 문화 제국주의 운운하면서 언어의 기원이나 우열 같은 거 따지는 짓을 절대 금기시하고 불가지론으로 부치고는 있다. 그러나 언급을 꺼린다고 해서 실체 자체가 없지는 않을 것이다.;; 그렇다고 공개적으로 거론하는 것도 덕이 안 되는 짓이고.. 참 어려운 문제이다. ㅎㅎ

Posted by 사무엘

2019/08/07 08:34 2019/08/07 08:34
, , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1648

1. 완전히 새로운 알고리즘 분야

컴퓨터는 정말 대단한 기계이다.
정보의 최소 단위인 0과 1을 분간하고, 임의의 주소가 가리키는 메모리의 값을 읽거나 쓸 수 있고 프로그램의 실행 지점도 메모리의 값을 따라서 변경 가능하게 했더니(튜링 완전) 그야말로 무궁무진한 양의 정보를 가히 무궁무진한 방식으로 처리가 가능해졌다.

이런 이론적인 근간이 마련된 뒤에 반도체의 집적도가 더 올라가고 메모리와 속도가 더 올라가고 가격이 더 내려가는 건 그냥 시간 문제일 뿐이었다.
그런데.. 단순히 복잡한 계산이나 방대한 검색을 빠르게 해내는 것만으로 컴퓨터가 인간의 고유 영역을 완전히 침범하고 대체했다고 보기는 곤란하다. 그건 그냥 자동차가 인간보다 더 빠르고 중장비가 인간보다 더 힘센 것만큼이나, 기계가 인간의 역할을 일부 보조하고 확장하는 것일 뿐이다.

물론 단순히 동력과 관련된 분야는 말이나 소 같은 동물도 인간보다 약간이나마 더 우위에 있긴 했다. 그에 비해 정보 처리 분야는 자연계에 지금까지 인간의 라이벌 자체가 아예 존재한 적이 없었다는 차이가 있다.
그러나 인간도 속도가 느리고 개인의 능력이 부족할 뿐이지.. 많은 인원을 동원하고 많은 시간만 주어지면 기계적인 정보 처리 정도는 '유한한 시간' 안에 언젠가 다 할 수 있다. 일을 좀 빠르고 정확하게 수행하는 것만 갖고 '창의적이다', '인간을 닮았다'라고 평가해 주지는 않는다.

정렬과 검색에, 다이나믹이니 분할 정복이니 하는 최적해 구하기처럼 고전적인 분야에서 고전적인(?) 방법론을 동원하는 알고리즘은 이미 수십 년 전에 다 연구되어서 깔끔한 결과물이 나왔다. 그런 건 이미 대학교 학부 수준의 전산학에서 다 다뤄지는 지경이 됐으며, 정보 올림피아드라도 준비하는 친구라면 아예 중등교육 수준에서 접하게 됐다.

그런데 현실에서는 그렇게 깔끔하게 떨어지지 않는 더 복잡하고 난해한 문제를 풀어야 한다. 깔끔하게만 접근했다가는 시간 복잡도가 NP-hard급이 되어 도저히 감당할 수 없는 문제를 적당히 타협하여 풀어야 한다.
중· 고등학교의 고전역학 문제에서는 "공기의 저항은 무시한다" 단서가 붙지만, 대학교에 가서는 그런 것까지 다 고려해야 하는 것처럼 말이다.

대수적으로 답을 구할 수 없는 문제에 대해 근사치를 효율적으로 구하기 위해 수치해석이라는 기법이 등장했듯, 전산학에도 각종 휴리스틱과 근사 알고리즘이라는 게 존재한다. 압축 알고리즘으로 치면 무손실이 아닌 손실 분야인 셈이다. 구체적인 건 학부 수준을 넘어 대학원에 소속된 별도의 연구실에서 다룰 정도로 난해하다.

그런데.. 이런 것들은 여전히 사람이 범접하지 못하는 분량의 계산 문제를 최대한 빠르게 효율적으로 푸는 방법에 대한 연구이다. 그런 것 말고 사람은 간단히 하는데 컴퓨터에게는 굉장히 난해해 보이는 일이 있다.
컴퓨터로 하여금 텍스트나 음성 형태의 인간의 자연어를 알아듣고 타 언어로 번역한다거나, 그림으로부터 글자 같은 정보를 알아보게 할 수 없을까?
컴퓨터를 바둑· 장기· 오목 같은 게임의 고수로 키울 수 없을까?

이건 단순히 TSP(순회하는 세일즈맨 문제)를 더 그럴싸한 가성비로 다항식 시간 만에 푸는 것과는 분야가 다르다.
저런 걸 기계가 인간과 비슷한 속도와 정확도로만 해내더라도 굉장한 이득이다. 기계를 부리는 비용은 인간을 고용하는 인건비보다 넘사벽급으로 저렴한 데다, 기계는 인간 같은 감정 개입이 없고 지치지 않고 실수도 전혀 하지 않기 때문이다.

하물며 속도와 정확도가 인간 전문가의 능력을 능가하게 된다면 게임 끝이다. 기계적인 단순 노동력이나 판단력만을 요구하는 일자리는 사라지며, 인간은 기계가 대신할 수 없는 더 창의적이고 전문적인 일자리로 갈아타야 할 것이다.

2. 흑역사

소위 '인공지능'에 대한 연구는 진공관이니 트랜지스터니 하던 무려 1950년대 컴퓨터의 초창기 때부터 천조국의 날고 기는 수학자, 컴퓨터 공학자들에 의해 진행돼 왔다. 특히 세부 분야 중 하나로서 기계번역도 연구됐으며, 1954년에는 조지타운 대학교와 IBM이 공동 연구 개발한 기계번역 솔루션이 실제로 출시되기도 했다.

인류 역사상 최초로 기계번역이란 게 연구된 언어는 러시아어 → 영어이며, 이는 전적으로 냉전 덕분이다. 하긴, 2차 세계 대전 때는 번역이 아니라 암호를 해독하는 기계가 개발되긴 했었다. 적성국가들의 언어 중 일본어는 영어와의 기계번역을 연구하기에는 구조가 너무 이질적이고 어려웠을 것이다.

그래도 인간 번역가가 아닌 컴퓨터가 러시아어 텍스트로부터 영어 텍스트를 허접하게나마 뱉어 내자 학계와 업계는 흥분했다. 이런 식으로 조금만 더 연구하면 컴퓨터가 금방이라도 세계의 언어 장벽을 다 허물어 줄 것 같았다.

그때는 학자들이 자연어에 대해서 뭔가 순진 naive하게 원리 원칙대로 규칙 기반으로, 낭만적으로 접근하던 시절이었다. 인간의 언어도 무슨 프로그래밍 언어처럼 유한한 문법과 생성 규칙만으로 몽땅 다 100% 기술 가능하고 parse tree를 만들고 구문 분석이 가능할 거라고 생각했다. 물론 그 규칙이 간단하지는 않겠지만, 촘스키 같은 천재 언어학자 몇 명을 외계인과 함께 골방에다 갈아 넣고 며칠 열나게 고문하면 다 찾아낼 수 있을 것이고.. 그러면 언어의 기계 분석은 게임 끝이지 않겠냐 말이다.

궁극적으로는 전세계 모든 언어들의 교집합과 합집합 요소를 망라하는 중간(intermediate) 언어도 만들 수 있을 것이라고 생각했다. 세계 각국의 언어들을 그 중간 언어와 번역하는 시스템만 만들면 전세계 사통발달 언어 번역 시스템을 만들 수 있지 않겠는가? 이 정도 생각은 나조차도 한 적이 있다.

그랬으나.. 뚜껑을 열어 보니 영광은 거기서 끝이었다.
기계번역은 빵점 백지 상태에서 4, 50점짜리 답안을 내놓는 것까지는 금방 할 수 있었지만, 거기서 성적을 7, 80점짜리로라도 올려서 실용화 가능한 상품은 오랫동안 연구비를 아무리 투입해 줘도 선뜻 나오지 않았다.
인간의 언어라는 게 절대로 그렇게 호락호락 만만하지 않고 매우 불규칙하고 복잡한 구조라는 게 연구하면 연구할수록 드러났기 때문이다. 지금까지 사용한 연구 방법론 자체가 약발이 다하고 한계에 다다랐다.

이 때문에 1970년대에는 돈줄을 쥔 높으신 분들이 "인공지능"이란 건 밥값 못 하는 먹튀 사기 허상(hoax)일 뿐이라고 매우 비관적이고 보수적으로 생각하게 됐다. 컴퓨터는 그냥 계산기일 뿐, 그 돈으로 그냥 인간 번역가나 더 양성하고 말지..
이 단어 자체가 학계의 흑역사 급으로 금기시되어 버렸다. 인공지능이란 게 키워드로 들어간 논문은 저널에서 믿고 걸러냈으며, 관련 연구들의 연구비 지원도 모조리 끊길 정도였다.

이 현상을 학계에서는 제1차 AI 겨울(혹한기, 암흑기, 쇼크, 흑역사 등등...)이라고 부른다. 과거의 무슨 오일 쇼크 내지 게임 업계 아타리 쇼크처럼 말이다.
그렇게 고비를 겪었다가 더 발달된 연구 방법론으로 활로가 발견되고, 그러다가 또 2차 겨울을 극복한 뒤에야 요 근래는 인공지능의 중흥기가 찾아왔다고 여겨진다.

3. 문제는 데이터

지금은 기계번역이건, 게임 AI이건, 패턴인식이건 무엇이건.. 인공지능의 주재료는 규칙이 아니라 데이터이다.
기계번역 시스템을 개발하는데 언어학 문법 지식이 동원되지 않으며, 보드 게임 AI를 만드는데 통상적인 게임 규칙 기반의 알고리즘이 동원되지 않는다. 이상한 노릇이 아닐 수 없다.

그러는 게 아니라 요즘 인공지능이라는 것은 아이디어는 매우 간단하다. 기출문제와 정답을 무수히 많이, 인간이 상상할 수도 없을 정도로 많이 주입시켜 준 뒤, 이로부터 컴퓨터가 규칙성을 찾아내고 새로운 문제가 주어졌을 때 정답을 추론하게 하는 방법을 쓴다. 해결하고자 하는 문제를 기술하고 정답의 조건을 명시하고 알고리즘을 구현하는 걸 인간이 일일이 하는 게 아니라.. 그 자체를 컴퓨터가 알아서 하게 하는 것이다.

이것이 '기계학습', 그 이름도 유명한 machine learning이다. 이것이 이전에 인공지능을 구현하는 방법론이던 '전문가 시스템'을 대체했다. 이런 무지막지한 방법론이 적용 가능할 정도로 요즘 컴퓨터의 속도와 메모리가 매우 크게 향상된 덕분이다.

인간의 입장에서 기계학습을 시키는 방식은 지도(supervised learning) 또는 비지도 학습으로 나뉜다.
그리고 기계의 입장에서 학습(?)을 실제로 수행하는 방법으로는 인공 신경망, 앙상블, 확률(은닉 마르코프 모델), 경사/기울기 하강법 같은 여러 테크닉이 있는데, 기울기 하강법은 복잡한 선형 방정식을 푸는 심플렉스와 비슷하다는 느낌도 든다.

인공 신경망은 생물의 신경망이 동작하는 원리에서 착안하여 만들어진 기계학습 모델이라고는 하지만 당연히 실제 인간 뇌의 작동 방식에 비할 바는 못 된다.
MLP니 CNN이니 RNN이니 하는 신경망 용어들이 존재하며, 그리고 이 인공 신경망을 어떻게 하면 잘 갖고 놀 수 있을까 고민하는 연구 분야를 '딥 러닝'(심층학습)이라고 한다. 마치 네트워크 계층의 다양한 기술 용어만큼이나 AI에도 계층별로 다양한 기술 용어가 존재한다.

게임 AI라면 단순히 뭔가를 인식하고 분류만 하면 장땡인 게 아니라 뭔가 극한의 최적해를 찾아가야 할 텐데.. 이런 걸 학습시키는 건 딥 러닝의 영역이다. 알파고처럼 말이다. 그런데 알파고 하나가 지구상의 최고의 인간 바둑 기사를 이긴 것은 물론이고, 다른 재래식 알고리즘으로 십수 년간 개발되어 온 기존 바둑 AI들까지도 다 쳐발랐다니 무서운 일이 아닐 수 없다. 뭐, 개인용 PC 한 대만으로 그렇게 동작하는 건 아니긴 하지만 말이다.

오늘날 연구되고 있는 인공지능은 무작정 인간과 동급으로 생각하고 창조하는 기계는 당연히 아니고, 컴퓨터의 막강한 메모리와 계산 능력으로 지금까지 주어진 데이터를 토대로 새로운 상황에 대처하는 답안을 꽤 그럴싸하게 제시하는 '약한 인공지능'일 뿐이다.

쉽게 말해 "서당 개 삼 년이면 풍월 읊는다"처럼 말이다.
추리소설를 한 1000편쯤 읽고 나니 다른 새로운 추리 퀴즈에도 설정이 뻔히 보이고 답이 보인다.
드라마를 1000편쯤 보고 나니 비슷비슷한 드라마들은 스토리 전개가 어찌 될지 '안 봐도 비디오'처럼 된다. 그런 것 말이다.

그런데 저게 말처럼 쉬운 일인 건 아니다.
학습 대상인 무수한 텍스트· 이미지· 음성 데이터 내지 각종 게임 복기 데이터를 어떤 형태로 수치화해서 벡터 형태로 표현할 것인가?
그리고 '학습'이라는 걸 하는 동안 해당 AI 엔진의 내부에서는 구체적으로 무슨 계산 작업이 행해지는가?
컴파일러만 해도 결과물로 OBJ 파일이라는 게 생기는데, 그 내부적인 학습 상태는 어떤 형태로 표현되며, 이것만 따로 저장하고 불러오는 방법이 존재하는가? 본인은 AI알못이다 보니 전혀 모르겠다. ㅡ,.ㅡ;;

수천, 수만, 아니 그 이상 셀 수 없이 많은 숫자들로 이뤄진 벡터 I가 또 수없이 많이 있다고 치자. 이 숫자들은 현실 세계를 표현하는 미세한 자질을 표현한다.
그런데 어떤 블랙박스 함수 f가 있어서 f(I_1..n)에 대한 결과가 O_1..m라는 벡터 집합으로 나왔다고 한다.

컴퓨터는 이 I와 O 사이에서 규칙성을 찾아서 I에 대해 O와 최대한 비슷한 결과를 산출하는 함수 f를 구한다. 그러면 이제 임의의 다른 아무 input에 대해서도 수긍할 만한 출력 결과를 얻을 수 있을 것이다.
패턴 인식? 기계번역? 유사 작곡이나 창작? 현실에서 해결하려는 문제가 무엇이건 machine learning이 하는 일은 본질적으로 저걸로 요약된다. 내가 AI 쪽으로 아는 건 이게 전부이다.

지금은 TensorFlow 같은 범용적인 기계학습 엔진/라이브러리까지도 구글 같은 괴물 기업에 의해 오픈소스로 몽땅 풀려 있으며, 이걸 파이썬 같은 간편한 스크립트 언어로 곧장 돌려볼 수도 있는 세상이 됐다.
그런 라이브러리를 직접 개발하고 유지보수 하는 것까지는 바라지도 않는다. 방대한 현실 데이터를 수집해서 저기에다 적절하게 집어넣고, 이로부터 고객이 원하는 유의미한 추세나 분석 결과를 얻는 것만 해도 뭔가 프로그래밍 코딩과는 별개로 아무나 할 수 없는 전문 영역의 일이 돼 있다.

오늘날 AI 엔진의 연구를 위해서는 근간 이론이라 할 수 있는 선형대수학, 편미분, 확률 통계는 무조건 먹고 들어가야 된다. 엔진 코드를 직접 다루지 않고 쓰기만 하는 사람이라도 엔진이 어떤 원리로 돌아가는지 정도는 알아야 가장 적절한 방법론/알고리즘을 선택할 수 있을 테니 저런 것들을 맛보기 수준으로라도 알아야 할 것이다.

과거에 정보 사냥 대회가 있었던 것처럼 이제는 주어진 데이터로부터 새로운 문제를 잘 푸는 기계학습 모델을 설계하는 것이 경진대회의 아이템 내지 학교와 직장의 과제가 될 것으로 보인다. 컴퓨터가 할 수 있는 일이 더 늘어난다면 사람만이 할 수 있는 일은 그보다 더 수준 높고 추상적인 쪽으로 이동할 수밖에 없으니 말이다.

아무리 그래도 그렇지 자연어의 문법과 어휘 자체를 전혀 모르는 상태에서 데이터 학습만으로 댓글이 선플인지 악플인지를 기계가 분간할 수 있는 걸까? 그래도 클레멘타인 영화에 늘어선 댓글이 선플인지 악플인지 판단하려면 그에 대한 특별한 학습-_-;;이 필요할 것 같다.

그리고 변화무쌍 복잡한 필기체의 인식이 아니라, 그냥 자동차 번호판의 정향화된 숫자 내지 겨우 QR 코드의 인식 정도는.. '영상 처리 기술'의 영역이지, 저 정도의 거창하게 기계학습이니 뭐니 하는 인공지능의 영역은 아니다. 그건 구분해서 생각할 필요가 있다.

오래 전부터도 각종 전산학 알고리즘 용어를 검색할 때 종종 걸려 나오긴 했는데.. 국내 개인 사이트 중에 AIStudy라는 곳이 있다. 나모 웹에디터가 있던 시절부터 존재했던 정말 옛날 사이트이다. 그런데 운영자가 내 생각보다 굉장히 어린 친구이다. 정말 대단할 따름이다.
당연히 과학고-카이스트 라인이려나 생각했는데 그렇지는 않고 일반고-서울대 테크를 타 있다. 앞날에 건승을 빌어 본다.

Posted by 사무엘

2019/07/06 08:33 2019/07/06 08:33
, , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1637

« Previous : 1 : 2 : 3 : 4 : 5 : 6 : 7 : ... 11 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/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:
2634694
Today:
1492
Yesterday:
1754