2007년 4월 14일 토요일

Linux x86 64 환경

데스크탑을 core2duo로 업그레이드하면서 64비트 리눅스의 세계로 빠져들었다.

사실 현재 시점에서는 64비트 데스크탑 OS는 별 메리트가 없다.  좀 더 시간이 지나서 대용량 홈 비디오 편집이라던가 그런게 일반화되거나, 엄청난 양의 데이터를 메모리에 갖고 있어야 하는 컴퓨터 게임이 나오거나 해야 상황이 달라지려나?  요즘의 기껏해야 전체 메모리가 수 GB 내외인 데다가 애플리케이션도 GB 단위의 메모리를 사용하는 애플리케이션이 없는 현재 상황에서는 메리트가 없다.

어쨌든...  새로운 세계의 도전을 핑계삼아 최근에 시도한 바로는 몇가지 걸림돌이 있었다.  문제는 과거의 ia32 바이너리들이다.

vmplayer - 의외로 그냥 까니까 동작했다.  호환 라이브러리만 (데비안/우분투의 경우 ia32-libs 및 ia32-libs-gtk) 잘 설치해서 쓰면 문제가 없다.  단 imhangul을 쓰고 있다면 imhangul도 GTK+ 호환성 라이브러리에 맞게 깔아야 해서 xim/nabi로 쓰는 게 속편하다.

enemy territory - 왜 nvidia glx가 호환성 라이브러리가 (nvidia-glx-ia32) 있는지 생각하다가 테스트해 보려고 설치해 본 것.  역시 설치하니까 아주 잘 된다.  (왠지 옛날보다 많이 죽는 느낌이 드는 것 같은데 -_-)

flash - 첫 번째 걸림돌.  standalone program이 아니라 다른 프로그램의 플러그인이기 때문에 골치가 아프다.   Adobe에서는 64비트 포팅은 다시 빌드하거나 포인터 변수 사용 고치는 정도의 간단한 문제가 아니고 현재 작업중이라고 한다.  가장 쉽고 간단한 방법은 nspluginwrapper를 이용하는 것.  일반 플러그인을 사용하는 것보다 꽤 CPU 로드가 높아서 (그래도 쓸만하지만) 궁극적인 솔루션이라고 할 수는 없다.

duncan:~/tmp$ tar zxvf install_flash_player_9_linux.tar.gz
...
duncan:~/tmp$ cd install_flash_player_9_linux
duncan:~/tmp/install_flash_player_9_linux$ linux32 flashplayer-installer
...
duncan:~/tmp/install_flash_player_9_linux$ nswrapper ~/.mozilla/plugins/libflashplayer.so

Java - 이게 가장 큰 문제이다.  sun java 1.4는 nspluginwrapper로 동작하지만, java5/java6는 동작하지 않는다.  IBM JRE도 AMD64 버전이 없긴 마찬가지이다.  blackdown java는 원래 java5/java6 버전이 없다.  이 문제는 Sun의 게으름과 무관심이 가장 큰 문제이다.  이미 JRE는 amd64로 포팅이 되어 있고 없는 부분은 plugin 인터페이스뿐이다.  flash와는 달리 컴파일만 하면 해결되는 문제라는 얘기다.  J2SE 소스코드를 받아서 고쳐보려다가 참고 그냥 blackdown java만 깔아 놓았다.  이래서 자바가 진작에 오픈소스가 됐어야...

브라우저 문제를 해결하는 가장 현실적인 방법은 32비트로 빌드한 웹브라우저를 사용하는 것이다.  swiftfox를 사용하는 게 한 가지 방법이다.


결론적으로...  현재 새로 까는 사람들은 그냥 32비트 리눅스를 설치하기를 권장 -_-  (과연 ia32는 언제까지 존속할 것인가?)   일단 현재까지의 내용만 정리해서 flash 데비안 패키지도 nswrapper 사용하도록 고쳐서 버그 보내 보고 데비안 imhangul 패키지도 ia32 호환 버전 빌드하고 할 예정. 

2007년 4월 9일 월요일

데비안의 선호 투표 해석하는 방법

데비안은 가끔 "투표"를 한다. 데비안 개발자라면 투표권이 주어지는데, 마침 2007년 리더 투표가 있었고 어제 Sam Hocevar가 당선되었다는 결과 발표가 있었다.  음 그런데 이 웹페이지를 보면 대체 무슨 소리인지 잘 알기 어렵다. 뭔가 복잡한 용어가 등장하면서 수식이 등장해서 잘 파악하기 어렵다. 나도 처음에는 상당히 생소했기에, 한번 이 글에서 데비안의 투표 방법인 Condorcet method를 설명해 보려고 한다.

투표자의 갈등

우리가 정치 활동을 하면서 하게 되는 투표는 그 방법이 아주 간단하다. 후보가 몇 개가 있으면 그 중에서 자기가 원하는 후보를 하나 찍고 가장 많은 투표를 획득한 후보가 당선/선택된다. 하지만 찬반투표가 아니라면 실제로 우리가 투표를 할 때도 흔히 고민하게 되는 다음과 같은 문제가 있다.

  • 사표 방지 심리 - 내가 좋아하는 후보는 따로 있는데, 당선이 안 될 것 같다.  차라리 정책이 비슷하면서 당선 가능성이 있는 사람에게 표를 몰아주고 싶다.
  • 절대적 지지 후보 없음 - 이 놈이나 저 놈이나 다 똑같다. 역시 당선 가능성 있는 사람중에 차악을 선택해야 되나?
우리 일상생활의 "한 표"의 행사라는 게 그렇게 고민덩어리이다. 내가 가진 신성한 이 표가 너무 무의미해 보인다. 결국 유행에 밀려 유력 후보를 찍을 수밖에 없고, 정치적인 성향이 분명치 않은 사람은 자기 의견을 투표로 표현하기도 어렵다.

선호 관계 투표

Condrcet method에서는 적어도 위와 같은 고민은 없다.  투표를 할 때 한 사람을 찍는 게 아니라, 여러 명의 선호 관계를 기술하는 방식이기 때문이다.  데비안의 투표 용지를 이용해 보면,

[   ] Choice 1: cwryu
[   ] Choice 2: crew
[   ] Choice 3: clue
[   ] Choice 4: None Of The Above
투표용지는 1234 네 가지의 선택 사이의 선호 관계를 기술하게 된다.  더 선호하는 쪽에 작은 번호를 붙인다.  "2 1 3 4"를 써 넣으면 crew가 cwryu다는 좋다는 이야기이고 cwryu가 clue보다 좋다는 이야기이다.  내가 원하는 후보가 choice 1이지만 당선 가능성이 없다면 그냥 원하는 후보를 1로 쓰고 다음에 차악을 최악보다 우선적으로 선택하면 된다. 

[ 2 ] Choice 1: cwryu
[ 1 ] Choice 2: crew
[ 3 ] Choice 3: clue
[ 4 ] Choice 4: None Of The Above

그래도 좀 나은 후보가 1번인데 2번이나 3번이나 다 똑같은 놈같으면?  Choice 1에 1번을 붙이고 2/3번에 같은 번호를 쓰면 된다.

[ 1 ] Choice 1: cwryu
[ 2 ] Choice 2: crew
[ 2 ] Choice 3: clue
[ 3 ] Choice 4: None Of The Above

개표

왜 이렇게 써 넣어도 내 의견이 반영될 수 있는지, 개표 과정을 설명하면... 

이렇게 수집된 투표는 수 많은 "A to B" 선호의 집합이라고 할 수 있다.  몇 가지 후보 중에서 후보가 A와 B 둘이라고 할 때 A를 B보다 선호하는 사람이 있을 수도 있고 B를 A보다 선호하는 사람이 있을 수 있다.  2007년 리더 투표 페이지의 beat matrix가 그 투표를 모아 놓은 것이다. 그러면 각각의 pair에 대해서 어느쪽을 선호하는 사람이 더 많은 지 생각할 수 있다. 각각의 후보를 node로 하고, 후보 A가 B보다 우세하다는 관계를 A to B의 edge로 표현하면 웹페이지에 나온 그래프가 된다. 

즉 사표 방지심리를 가질 필요없이, 내가 선호하는 후보를 1번으로 기입하면 설령 그 후보가 당선권에서 멀어지더라도, 차악을 선택할 수 있고 그 표가 똑같이 반영된다.  절대적으로 선호하는 후보가 없더라도 특히 싫어하는 후보를 명시한다면 그 후보를 떨어뜨리는 정도로라도 자기 표로 의사를 표현할 수 있다.

애매한 경우

이 그래프가 이번 2007년 리더 투표처럼 한 사람이 모든 사람을 이기면 관계가 없지만 (이런 식으로 결과가 나오는 게 보통), 이 관계가 circular relation이 된다면 복잡해 진다.

이런 상황에서는 (오리지널 Condorcet method는 이 상황에 대한 해결 방법이 없지만) Schulze dropping 방법에 따라 몇 가지 기준에 따라 승자를 결정한다.  첫 번째로 선호 관계에서 얼마나 더 많은 후보를 제쳤느냐가 기준이 된다. 즉 그래프에서 outgoing edge와 incoming edge의 개수를 기준으로 승자를 결정할 수 있다.  그리고 만약에 이걸로도 결정할 수 없는 상황이 된다면, 그렇게 circular relation이 되는 관계만을 추려낸 다음에 가장 약한 (표 차이가 작은) 선호관계를  하나씩 없애서 circular 관계가 아닐 때까지 계속 한다.  예를 들어 A와 B와 C가 circular하게 선호하는 관계라면 A to B, B to C, C to A의 관계중에 가장 약한 관계를 drop한다.

그래도 동률이라면????

...
...

우리나라 국회의원 선거처럼 나이 많은 사람이 당선되는 건가?   -_-

그 상황이 된다면 투표 알고리즘만으로는 해결할 방법이 없다.  그런 상황이 계속해서 벌어진다면, 과연 투표라는 게 인간 사회의 의사결정 방법으로 올바른 방법인지 진지하게 생각해 볼 필요가 있을 듯...

2007년 4월 7일 토요일

어색한 번역 습관

어색한 메세지 번역을 피하는 팁 몇가지에 이어...서 쓰는 건 아니고 관련 있는 몇 가지 메모:

한자를 붙여 신조어 만들기: 비(非)~, ~자(者), ~기(機)


우리가 일상생활이나 컴퓨터에서 쓰는 단어 중에 분명히 비~, ~자, ~기라는 단어가 있고, 많이 쓰는 건 사실이다.  nonpreemptive/비선점, editor/편집기, constructor/생성자, manager/관리자 등등등..  이러한 단어들이 만들어지게 된 유래가 (상당부분 중국과 일본에서 만든 한자 차용) 옳은지 그른지는 재쳐두고라도, 번역할 때 이러한 단어를 임의로 만드는 일은 정말 바람직하지 않다.   non-free - 비자유?, tokenizer - 구문분석자?, monitor - 감시기?  일단 보기에 어색하다.

이미 익숙하게 쓰는 단어가 아니라면 "비~" prefix가 한글로 붙었을 때 그게 부정의 의미인지 파악하기 어렵고, "~기"나 "~자"를 소프트웨어에 사용하는 것도 우리말에 자연스럽지 않다.

살아있는 소프트웨어

흔히 이야기하는 "수동태를 쓰지 말라"는 번역 팁과 연관있는 이야기로, 우리말에선 생명체가 아닌 존재에 동사를 잘 붙이지 않는다. 무생물은 주체적이지 않다.  (철학적인 문제?)

예를 들어 프로그램의 메세지에서 "I"와 "YOU"를 사용하는 말이 나올 때 상당히 고민하지 않으면 자연스럽게 번역하기 힘들다. 흔히 영문 메세지 원문에서는 소프트웨어가 생명을 가지고 사용자와 대화하는 것처럼 I를 주어로, you를 목적어로 사용하는 경우가 있는데 "나는", "당신은"이라고 번역하기 시작하면 번역 결과물이 상당히 곤란해 진다.

마땅히 무슨 말을 써야 한다는 정답은 없고, 아예 I나 you를 번역문에서 언급하지 않고 충분히 뜻이 통하도록 적당히 번역하는 게 가장 좋은 것 같다.

2007년 4월 4일 수요일

쓰레드별 POSIX locale

홈디렉토리를 정리하다가 예전에 쓰레드별로 다른 로케일 쓰는 방법을 찾아보다가 작성했던 예제 코드 발견.  glibc 전용이긴 하지만 지금 서치해 보니 darwin에도 구현되어 있다.  (MS에는 GetThreadLocale, SetThreadLocale 따위, 꼭 필요한 상황은 많지 않다 보니 그다지 쓰이지는 않는 듯...)

#define _GNU_SOURCE

#include <pthread.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>

struct tm tm = { 0, };

void *
thread_func()
{
  char buf[256];
  int n;
  locale_t l;

  l = newlocale(LC_ALL_MASK, "ko_KR.UTF-8", 0);
 
  uselocale(l);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  uselocale(LC_GLOBAL_LOCALE);
  freelocale(l);
}

int
main(int argc, char *argv[])
{
  pthread_t t;
  char buf[256];
  int n;

  setlocale(LC_ALL, "C");

  pthread_create(&t, 0, thread_func, 0);
  pthread_detach(t);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
  sleep(1);
  n = strftime(buf, 256, "%b %A %a", &tm);
  buf[n] = '\0';
  puts(buf);
 
}

실행해 보면 이렇게 두 개 스레드가 다른 로케일을 사용한다.

$ ./a.out
Jan Sunday Sun
 1월 일요일 일
Jan Sunday Sun
 1월 일요일 일
Jan Sunday Sun
 1월 일요일 일
Jan Sunday Sun

2007년 3월 28일 수요일

데비안 문제 (3) - 메인테이너와 패키지에 대한 권한

데비안 문제 (1) - unstable,
데비안 문제 (2) - 새 패키지 큐와 FTP 마스터 에 이어..

데비안 메인테이너가 된다는 건 무엇을 말하는 걸까?  free software project에서 보기 드문 복잡한 테스트를 거쳐서 "DD"가 되면  "@debian.org" 메일 주소를 가지고 있으며, 데비안 머신에 계정을 이용할 수 있고, debian-private 메일링 리스트에서 공개되지 않은 플레임^H^H^H메세지를 읽을 수 있고 (3년 후 공개된다), 각종 투표에 한 표를 행사할 수 있다.  하지만 '메인테이너'란 말 그대로 패키지의 메인테인 권한을 갖는 게 가장 큰 부분이다.

데비안 프로젝트가 이렇게 발전한 데는, 배포판을 다루고 있다는 점과 패키지 시스템이 잘 만들어져 있다는 점이 큰 몫을 했다.  각각을 패키지 단위로 쪼개고 각 패키지를 한 명의 메인테이너에게 배정할 수 있기 때문에 (패키지의 Maintainer: 필드가 있다는 점) 데비안의 scalability에 큰 영향을 미쳤다.  세계 어디에 1000명이나 되는 개발자가 한 가지 목표를 위해 참여하고 있는 OSS 프로젝트가 있을까?  물론 패키지 사이에 복잡한 상호관계가 (의존, 충돌 등등) 있긴 하지만 다른 사람이 어떤 작업을 하고 있는지 거의 몰라도 패키지를 만드는 데는 문제가 없는 경우가 많다.  그래서 보면 패키지 한 두개만을 담당하면서 메일링 리스트도 거의 읽지 않고 자기만의 세계에 빠져서 그 패키지만 업데이트하는 걸로 메인테이너를 유지하는 사람들도 꽤 있다.

이 데비안의 scalability와 패키지간의 독립성이 갖는 장점이 조금씩 상처를 받게 된 건 최근인 것 같다.  먼저 사람 수가 몇배가 넘게 늘었고, 리눅스에서 돌아가는 프로그램들이 의존성을 두려워하지 않는다.  과거에는 그야말로 라이브러리라고는 libc에만 의존하는 프로그램이 상당수였고, 기껏해야 bdb를 사용하고 X 프로그램이래봐야 X11, 조금 복잡하면 Xt/Xaw를 사용하는 정도로 의존성을 늘이는 데 주저하는 경향이 있었지만 요즘은 그렇지 않다.  서슴치 않고 라이브러리를 이용한다.  이제는 메인테이너들 사이에 긴밀한 협조가 필요하다.

그런데 종종 메인테이너가 시간이 없거나, 실력이 부족하거나, 아니면 성격이 괴팍하다고 밖에 볼 수 없는 이유로  협조가 제대로 되지 않는 일이 발생한다.  오랜 시간동안 메인테이너가 응답하지 않아서 버그 수정이 제대로 되지 않는 일이야 흔한 일이고, 버그를 수정하지 못하는 경우도 많다.  이런 상황이 벌어졌을 때 나름대로 도움을 요청하거나 "NMU 해 버려"라고 하는 아량을 가졌다면 괜찮은데 그것도 아니고 질질 끄는 상태가 되기도 한다.  또 정말 "나쁜" 메인테이너는 "그게 왜 버그냐. 건드리지 마"식으로 일관하는 사람도 분명 있다.  사람 사는 곳이야 어디나 괴팍한 사람도 있게 마련이지만, 그런 일이 발생했을 때 특정 패키지, 특히 중요한 패키지 몇개가 다른 패키지를 따라가지 못하는 상황에 빠지면 난감하기 짝이 없다.  (예를 들어 보면, 데비안의 GDM 패키지는 다른 gnome 패키지처럼 유기적으로 움직이지 않는다.)

이러한 강력한 메인테이너쉽은 제도적인 근거도 있다.  constitution 3.1에 규정된 바에 따르면 "An Individual Developer may make any technical or nontechnical decision with regard to their own work".  물론 이 권한을 override할 수 있는 권한이 테크니컬 커미티에게 있다: "The Technical Committee may ask a Developer to take a particular technical course of action even if the Developer does not wish to; this requires a 3:1 majority. For example, the Committee may determine that a complaint made by the submitter of a bug is justified and that the submitter's proposed solution should be implemented."  하지만 커미티의 이 권한 행사는 실제적으로 이루어지기 힘들다. 3:1 의견이 나오기도 쉽지 않은 일이지만, constitution 규정이 만들어진 이후로 수십배로 커진 데비안의 규모에 따라 그만큼 늘어난 각종 갈등에 대응하기도 어렵다.  실제로 지금까지 커미티가 결정한 사항도 라이센스 문제이거나, debian-policy의 명백한 위반처럼 사안이 명확하고 어떻게 결정해야 할 지도 명확한 것 외에는 개발자의 권한을 오버라이드하는 경우는 찾아볼 수 없다.  정답이 명확하지 않은 각종 정책적인 결정사항에 대해서는 그냥 패키지 담당 메인테이너에 따라 결정될 가능성이 99.99%이다.

아마도 우분투처럼 모든 패키지를 소스컨트롤하고, 모든 개발자에게 쓰기 권한을 주는 일은 데비안에서는 일어나지 않을 것 같다.  하지만 어떤 식으로든 메인테이너의 "패키지 소유"는 좀 약화시킬 필요가 있다.  실제로 패키지에 Uploaders: 필드가 구현되서 여러명이 권한을 가지는 Co-maintenance 방법도 있고 (실제로 잘 이용하고 있음), 스스로 권한을 축소시키는 Low Threshold NMU 방법도 있었다.  링크는 잊어버렸지만, 일단 etch 릴리스한 다음에 개인의 권한에 대해 constitution 개정을 시도하겠다는 제안도 있었다.  (실현은 어려울 것 같지만)

일단 나도 이러한 데비안의 "지나친 메인테이너쉽" 문제를 개선하는데 조금이라도 기여하기 위해..  메인테인하고 있는 모든 패키지를 alioth 등 데비안의 소스컨트롤에 등록할 예정이다.  그리고 가능하다면 원하는 모든 사람들에게 커미트 권한과 업로드 권한을 부여한다.  이 정도가 현재 할 수 있는 일이다.  (내 하드 디스크에서 계속 소스 관리하기가 피곤해서이기도 하고...)

2007년 3월 25일 일요일

Tomboy의 날짜/시간 포맷 오류 - mono locale 관련

Tomboy를 실행하다가 날짜와 시간이 한국 포맷으로 나오지 않는 것을 발견해서 예전의 퍼키옹이 한 경로를 그대로 추적을 해 봤습니다. 막상 이걸 봐도 실제로 문제점을 추적하기는 힘들더군요.  그래서 일단 버그부터 지른다음에 조금 기다려봤는데...  역시 그냥 버그 현상만 써 놓으니까 메인테이너도 고쳐주질 않을 것 같고 퍼키씨도 당장은 손 안 대는 것 같고 해서 직접 찾아봤습니다.

결국 퍼키옹이 따라갔던 경로를 하나하나 다 반복해 보고서는 문제를 파악했는데..  문제는 헤더 파일을 제너레이트하는 C# 프로그램이 소팅을 하면서 "ko-kr"을 "kok" (콘칸어) 뒤에 배치하는 바람에 C 코드에서 strcmp로 바이너리 서치를 할 때 못 찾는 문제였습니다.  String.CompareTo()를 간단히 String.CompareOrdinal()로 교체해서 해결.

그런데 여기서 끝나지 않은 게, 빌드를 잘못했는지 이제 각각의 "1월", "2월", "월요일" 따위의 이름은 한글로 나오는데 포맷이 어떤 부분은 제대로 나오고, 어떤 부분은 "12월 6 2006"과 같이 나오네요.

(업데이트) 나머지 문제는 C# culture info와 상관없이 tomboy에서 자체적으로 사용한 날짜 포맷을 번역할 때 고려하지 않은 사항.  tomboy 번역을 바로잡았으니 다음 릴리즈에는 제대로 나오겠네요.


2007년 3월 24일 토요일

구글 blogger.com - 한국 포털 블로그와의 잘 보이지 않는 장벽

뭐랄까.  구글은 디자인이나 사용성 등 기발한 상상력보다는 노동력이 투입되는 부분에 약한 면이 있다.  다른 글 읽으려고 blogger.com에 들어갔다가 오른쪽 위에서 자꾸 만들 수 있다고 유혹을 하길래 만들어 봤더니...

일단 뭔가 알 수 없는 어색함을 느낀다.  기계적인 번역만을 한 상태이고, 한국말로 사용성 테스트가 제대로 되지 않은 듯 하다.

사용자 삽입 이미지

사용자 삽입 이미지

이렇게 어색한 번역도 그렇고..  확실히 테스트가 안 된 것처럼 정렬도 영문 순서로 되어 있다.

사용자 삽입 이미지

나도 한국 포털의 인위적 조작에 대해 상당히 반감을 갖고 있지만, 이런 건 사람이 노동력을 좀 투입해 줘야..  -_-

(일단 한국말로 보면 어색하다는 거 빼고는.. 온갖 기능들은 상당히 뛰어나다.)