2013년 1월 3일 목요일

나쁜 사마리아인들 - 장하준


나쁜 사마리아인들

장 하준의 경제학 파노라마
앞표지
부키, 2007 - 383페이지







한국에 살고 있는 내가 하루를 살아가면서 사용하는 물건들, 먹는 음식들이 어디서 왔는지를 하나하나 알아보면 우리나라에서 만들어진 것이 도 흔치않다. 사용하는 노트북은 중국에서 만들어졌고 스마트폰도 외국기업의 제품이며 먹는 음식들도 세계 곳곳에서 수입해온 재료로 만들어졌다. 이렇게 자유로워진 무역은 우리에게 좋은 물건을 싼 가격에 사용할 수 있게도 해주고, 국내 기업들이 경쟁을 통해 발전할 수 있는 동기도 주는 좋은 점이 많다.

그래서인지 WTO, IMF등은 신자유주의적인 정책(자유시장, 작은 정부, 규제의 최소화 등) 이 경제 발전의 해법이라고 생각하여 개발도상국들에게도 자유무역을 권하고, 국내 재정정책, 통화정책 등에도 충고를 한다. 이러한 신자유주의적 세계화는 지난 25년여의 시간동안 지속되어 왔고 수 많은 개빌도상국들에게는 큰 도움이 되지 않았던 것으로 보인다. 지금까지 이루어져온 세계화 정책의 잘못을 이야기하는 책이 장하준 교수의 나쁜 사마리안들이다.

이 책의 요지는 현재 진행되고 있는 자유시장, 세계화는 어느 정도 개발이 되고 세계 무대에서 싸울 능력을 갖춘 나라-한국도 이 단계에 어느정도 다다른 것으로 보인다-에게 유리한 체제라는 것이다. 물론 단기적으로는 개발도상국들에게도 자유시장이 이익을 줄 순 있지만 눈 앞의 이익이 아닌 장기적인 나라 경제 자체의 성장을 위해선 무조건적인 세계화가 답이 아니라고 말한다.

책의 앞의 두 단원 정도는 현재 잘 사는 나라들이 어떻게 부를 쌓아나갔는지 역사적 사실을 보여준다. 그 뒤에서는 신자유주의자들이 주장하는 내용들을 하나하나 반박한다. (정확히 자유무역, 외국인 투자규제, 민영화와 공기업문제, 지적재산권, 재정 건전성, 민주주의와 경제발전, 문화와 경제발전에 대한 신자유주의자들의 견해에 대해 반박한다) 단순한 주장들의 나열이 아니라 실제로 현재의 선진국들이 외국인 투자규제, 자유무역등을 어떻게 이용하여 자신의 경제적 역량을 키워나갔는지를 보여주고, 민영화와 공기업 문제가 생각보다 간단한 문제가 아니라는 여러 예시를 보여준다. 또, 지적재산권의 필요성은 동의하지만 현재 지적재산권 제도의 문제점과 개선점에 대해서도 예시를 들어 말하고 있다. 그 밖에도 여러 논점들이 수많은 예시와 레퍼런스등을 통해 제시되고 있어 흥미롭게 읽을 수 있는 책이었다.



나도 경제학개론 수업에서 들은 적이 있는 리카도의 비교우위론을 기반으로 자유무역은 개발도상국이든, 선진국에게든 이익을 준다는 주장이 신자유주의자들의 주장의 핵심 중 하나이다. 장하준 교수는, 비교우위론은 물론 맞는 이론이지만 한계가 있다고 말한다. 이론에서 가정한 간단한 상황은 둘째치고라도, 비교우위론에 따라 자신이 현재 잘하는 것 (개발도상국의 경우 보통 큰 생산성을 갖지 못하는 산업이나 자원 수출정도에 그칠것이다)에 집중한다면 앞으로도 계속 현재 상태를 벗어날 수 없다는 문제가 있다. 한국이 60년대 가난한 나라에서 지금의 공업국가로 변할 수 없었을 것이고, 미국, 일본들도 마찬가지 였을 것이라고 말한다.

장하준 교수는 신자유주의자들의 여러 주장들이 그들의 말처럼 간단하게 적용되지 않는다고 주장한다. 언뜻 나빠보이는 재정 적자도 그 필요성이 존재할 때가 있고, 자국 내 산업을 보호하기 위한 관세, 규제들도 적절한 시기에 적절하게 사용된다면 그 나라의 경제적 역량을 높이는데 사용할 수 있다고 말한다.

선진국들은 자신들의 번영의 이유가 자유로운 무역이라고 말하며 개발도상국들에게 규제를 없애고 관세를 줄이고 자신이 현재 잘하는 것에 집중하라고 말하지만, 이 책을 읽다보면 항상 그것만이 정답은 아니라는 생각이 든다. 우리나라부터도 60,70년대 아무런 제한없이 초국적기업들이 우리나라에 들어와 사업을 했다면 현재 우리가 알고 있는 한국의 기업들은 존재 하지 않았을 것 같고 (그들과의 경쟁에서 살아남을 수 없었을테니까), 아직까지도 의류, 가발 등이나 파는 나라이지 않을까싶다.

물론 어느 정도 능력을 갖춘 뒤부턴 그러한 보호막이 오히려 해가 될 것이라는 것도 사실이겠다. 국제 경쟁력을 갖춘 뒤에는 외국 기업들과의 경쟁을 통해 스스로도 발전이 가능할 것이고 소비자들에게도 이익을 줄 수 있을테니까 말이다.


이 책을 읽기 전까지 나는 자유무역이나 세계화 등이 대부분의 경우에 좋고, 전 세계적으로 이루어야 할 시스템이라고 생각했다. 세계가 하나의 시장이 된다면 소비자들도 좀 더 좋은 선택이 가능하고 기업들도 정말 능력있는 기업들이 살아남을 수 있을테니까 말이다. 하지만, 현재 세계는 하나의 나라가 아니고 각각의 나라들마다 경제수준이 너무나 다르다. 이런 상황에서 아무런 보호막없이 개발도상국들에게 자유롭게 경쟁하라고 하는 것은 어른과 아이의 싸움같이 형식적으로만 '공평'한 것이 아닌가 싶다.

하지만 아직도 나는 우리나라는 이제 우리 내부에서만 경쟁하기보다 세계와 경쟁해야 할 시점이 왔다고 생각한다. 국가 내부의 경쟁이 너무 심해진 상태라고 생각하고, 좁은 한국만을 보고 경쟁하기보다 세계를 무대로 사업을 하고 경쟁할 수준이 어느 정도 되었다고 생각하기 때문이다. 지난 20세기 정부의 보호막을 바탕으로 많은 역량을 키웠으니 이제 나가서 경쟁해도 될 때가 되지 않았나라는 생각이 드는 한편. 한국 위의 북한을 비롯한 많은 아프리카 개발도상국들에게도 역량을 키울 기회를 주어야 하지 않나 라는 생각도 든다.

2013년 1월 1일 화요일

pintos project 1 - Threads

useful link:
http://www.scs.stanford.edu/07au-cs140/pintos/pintos_2.html#SEC15


Pintos project 1 은
1) Alarm clock
2) priority scheduling
3) Advanced scheduler
위의 세가지 기능을 구현하는 프로젝트이다.

내용상 가장 쉽고 금방 구현할 수 있는 프로젝트 이지만, 이 프로젝트로 핀토스를 처음 접하기 때문에 체감 난이도는 엄청 쉽지많은 않았다 (그래도 다른 프로젝트들에 비하면 엄청 쉽긴 했지만..).

1) Alram clock
device/timer.c의 timer_sleep()는 호출한 thread을 특정 시간 동안 'sleep' 상태로 만들어 진행 중 이던 작업을 지연시키는 역할을 하는 함수이다.
핀토스에 원래 구현되어 있는 timer_sleep()은 while문을 돌면서 매번 thread을 깨울 시간이 되었는지 안되었는지를 확인하는 busy wait으로 구현되어 있다. 따라서 while문을 도는 동안 다른 유용한 작업을 하지 못해 매우 비효율적인 디자인이라고 할 수 있다. 이 문제를 해결하는 것이 첫번째 alarm clock파트이다.

이 문제를 고치기 위해 device/timer.c와 threads/thread.c, threads/thread.h을 고쳐야 한다.
busy wait을 없애기 위해선 sleep된 thread을 보관할 sleep list을 직접 만들어야한다. 핀토스에 제공된 data structure중 하나인 list을 사용하는 것이 편리하고,  list 사용 방법은 thread.c의 ready_list을 보고 감을 잡을수도 있고, lib/kernel/list.c의 주석을 참고하면 쉽게 사용할 수 있다.

timer_sleep() 에서 while문을 없애고, sleep state로 만들 thread (timer_sleep()을 호출한 thread) 을 sleep_list에 넣고, 주기적으로 리스트를 확인하여 깨어날 시간이 된 thread만 sleep list에서 꺼내면 된다. (주기적으로 리스트를 확인하기 위해 timer.c의 timer_interrupt()함수을 이용하면 된다)

꺼낼 시간과 현재시간을 비교하기 위해 thread마다 깨어날 시간을 기록할 멤버변수가 필요하고, list에서 깨어날 시간이 작은 순서대로 정렬하기 위한 비교 함수도 필요하다.
몇몇가지 함수만 만들면 쉽게 alarm clock을 구현할 수 있다.

2) Priority scheduling
여러개의 thread들이 동시에 실행되고 있을때 synchronization을 위해 사용되는 도구는 lock, semaphore, condition등이 있다. 만약, 여러개의 thread가 하나의 lock을 기다리는 상황이 생기면 어떤 thread가 먼저 lock을 가질 수 있게 해야할지를 정하는 방법엔 여러가지 방법이 있다.
이 프로젝트에서는 thread마다 priority을 주고, 큰 priority을 가진 thread가 우선권을 가지는 priority scheduling algorithm을 구현한다.
이를 위해, thread.h에 thread의 멤버변수로 priority (0~63 사이의 값을 가질 수 있고, 숫자가 클수록 priority을 가진다. 기존의 구현에선 기본적으로 모두 PRI_DEFAULT(31)을 가지고 있다.)을 가지고 있다.
구현해야 되는 내용으로는 semaphore, lock, condition이 있다. 이 부분을 구현하기 전, semaphore, lock, condition이 무엇인지 수업 렉쳐노트 등을 통해 확실히 이해를 한 뒤 진행해야 수월하게 진행할 수 있을 것이다.

lock은 semaphore의 특수한 경우로 생각할 수 있으므로, 세마포어를 먼저 구현한다.

sema up, down pseudo code는 구글링을 해보면 위키백과 등 많은 곳에서 볼 수 있다. 따라서 구현하면 될 것이다.
(간단히 요약하면, semaphore의 value가 0이 아니면 value을 1 감소시키고 계속 진행시키고, value가 0이면 sema_down을 호출한 thread을 block시키고 value가 1 이상이 되길 기다린다. sema_up에선 해당 semaphore을 기다리고 있는 thread가 있다면 그 중 가장 priority가 큰 thread을 unblock시키고, value을 1 증가시킨다.)

semaphore구현이 끝나면 lock을 구현한다. lock과 semaphore의 차이점은 lock은 semaphore와 다르게 하나의 thread 만 얻을 수 있다는 점이다 (value 1인 semaphore인 셈). 따라서 lock은 자신을 현재 가지고 있는 thread로의 pointer을 가지고 있다.

lock_acquire와 lock_release에선 각각 sema_down과 sema_up을 사용한다. 하지만 좀 더 생각해 주어야 할 점이 priority donation에 의해 생기는 문제점들이다. 다양한 해결방법이 있겠지만, 내가 사용한 방법은 lock에 list_elem들을 추가하여, lock을 요청한 thread들의 list와 각 thread마다 보유하고 있는 lock list을 가지게 하여 해당 문제를 해결하였다. 자세한 알고리즘은 직접 생각해보는 것이 도움이 될 것이다. priority donation과 관련된 부분이 이 프로젝트에서 가장 어려운 부분이고 이것만 해결한다면 condition 구현 부분은 매우 쉽게 할 수 있을 것이다.

3) Advanced scheduler는 구현하지 않았다.