[book] 搞定一切,還有時間玩

對於我這個時間管理十分糟糕的人, 這本書提供了一些方法, 讓我有機會改進, 我十分不能專心, 常常做某件事心理就想著別件事>”<

我列出幾點書中提到, 然後我覺得對我應該會有幫助的方法

  • 給自己一點思考時間
  • 限制每件工作的時間
  • 先做你心中最抗拒的事情 (完全說到心坎裡去了…)

不過目前的我, 做什麼事情都沒什麼時間壓力, 難怪效率十分不張阿…

Advertisements

[Erlang] priority message passing notes

在Erlang User Conference 2006上, 看到一篇關於Erlang message passing的slide, 覺得蠻有趣的

Ref: http://www.duomark.com/erlang/briefings/euc2006/index.html

這篇slide分成3個部份

第1部份是講基本語法

第2部份就是我比較感興趣的地方, 他提到一個有趣的問題

問題描述:
在利用Erlang接受message的時候, 如果有一種priority message, 只要一接收到這種message, 就要先執行相對應的工作, 但是在Erlang的message model中, 他有一個message queue, 所有的message都會被丟到這個queue裡面, 照順序接收,他並不保證有某些message接收的順序是比較高的, 所以我們應該要怎麼解決這個問題?

解法:
其實這個問題並不是很好解決, 他先提出兩種polling的方法, 但是都不是很好, 而且一個process當中最好不要有兩個以上的receive message statement, 可能會有memory performance的問題, 所以他給出利用protocol溝通的方式:

分成router, high process, low process and data store 4個process, 簡單來說router會控制現在是要讓high process還是讓low process去access data store, 所以利用protocol來判斷兩個process當中的message queue, 一旦high process有要處理的message, 就擋掉low process!

flow-chart

第3部份:

介紹一種(event programming) pattern, 來避免利用一大堆State machine來實作(以後更改太困難…).

Description:
central event loop will call associate method according to the message. After the method executed, it will return the control to main loop. The main loop will dispatch messages for multiple process instance which is not blocking! Central event loop can detect asynchronous process message!!

Code:

event_loop(M, S) ->
    receive
        {From, Event} ->
            dispatch(From, Event, M, S);
        {From, Ref, Event} ->
            dispatch(From, Event, M, S);
        Other ->
            io:format(”Unknown msg: ~p~n", [Other]),
            exit({unknown_msg, Other})

    end.
% Recv will be the asynch process id
event_loop(M, S, Recv) ->
    receive
      {From, Event} when element(From, Recv) == [] ->
            dispatch(From, Event, M, S);
      {From, Ref, Event} when element(From, Recv) == Ref ->
            dispatch(From, Event, M, S);
      {From, Ref, Event} when element(From, Recv) == [] ->
            dispatch(From, Event, M, S)
    end.
% M:Event method can be asynchronous process
% which will return {ok, NewState, Recv}
dispatch(From, Event, M, S) when atom(Event) ->
    handle(M:Event(From, S), M);

dispatch(From, {Event, Arg}, M, S) ->
    handle(M:Event(From, Arg, S), M).
handle({ok, NewState}, M) ->
    event_loop(M, NewState);

handle({ok, NewState, Recv}, M) ->
    event_loop(M, NewState, Recv).

[bike] 2009/04/11-12 北橫二日遊

Day 1:

板橋->復興->巴陵

騎起來蠻累的>”<, 中間太陽也很大, 真是一場耐力的考驗…

Day 2:

巴陵->明池->宜蘭->市區

不得不誇讚明池到巴陵這段路真的很漂亮, 難以言喻, 有機會我要載妹來這附近的嘎拉賀溫泉洗野溪溫泉!!

結語:
其實機車真是個不錯的發明XD, 讓人不必這麼累就可以享受到不一樣的風景!

相簿:

http://picasaweb.google.com.tw/yuteh.shen/20090411Bike1st#

http://picasaweb.google.com.tw/yuteh.shen/20090412Bike2nd#

[bike] 2009/04/22 陽明山竹子湖

繼上次征服北橫後

這次在雨中從內湖->自強隧道->東吳大學->仰德大道->文化大學->竹子湖

Total 53.44 km, 算是半天行程

除了雨中騎起來別有一番滋味

上山一開始車子超多的

我還被一大群野狗追了50m…偏偏上坡騎不快T_T

看了一下文化大學的學生, 我真應該念文化大學的QQ (沒事跑去什麼宅男大學…)

到了竹子湖

跟我期望有點落差(OS: 我以為竹子湖是湖….)

吃了地瓜豆花~~蠻爽的

不過後來整個起霧, 能見度超低

騎起來也蠻特別的XD

回程就是連續的下坡

因為路面很差, 我不敢分心看時速表

有喵到最快是49km/hr

不過水就一直往臉上噴

害我不敢張嘴, 眼睛也是不看的很清楚

最後順利回到家

Song! 還是家裡最爽XDD~~

p.s 文化大學對面的牛肉麵是我吃過最難吃的…

    我自己煮都可以比她好吃…

[note] Multi-core & parallel programming knowledge

Ref: http://cgi.taiwan.cnet.com/referral/?uid=2000006303

今天看了以上關於parallel programming 和multi-core 的一系列影片, 才知道自己過去的錯誤認知XD

Why multi-core:
原來最跑出這東西的原因有三項

  • power
    在目前已經很高的CPU clock rate下, 為了增加13%的clock rate, 可能導致73%的功率消耗, 但如果我們把性能降到87%, 我們幾乎可以節省50%的功率消耗
  • instruction level parallel
    在提升CPU clock rate下, 從現行程式中找到可以並行的指令是越來越難
  • memory
    memory access的速度跟不上CPU clock rate增加的速度

以上都是造成目前往multi-core CPU方向走的原因之一

Parallel method:

  • Data parallel
    divide data into different part, and do the same work in each data part
  • Task parallel
    divide task into different task, and do the each task  separately

但是跟據Amdahl’s Law “速度的提升受程式中serial部分的限制,所謂serial部分,是指程式中不能並行執行的部分”, 所以無論怎麼增加CPU, 效率上的提升還是有所限制, 但是後來跑出一個人Gustafson, 他提出另一種看法, 我們可以讓電腦處理的資料提升, 就像有個程式需要跑500單位時間, 我們把並行的部分(ex: 200單位時間)增加一倍, 也就是在500單位時間內, 我們跑完700單位時間的工作, 那麼之前提到的serial 影響就會降到很低。

這就是超級電腦能夠成功運用並行技術的關鍵所在——我們不斷增加資料集,因為有了多核心處理器。

Key about parallel project:

  • scalibilty
    how to scale to 4-core, 8-core, 16-core
  • corresiton
    • race condition
    • dead lock
  • maintainability
    high abstraction

Abstraction Parallel programming

  • library
  • OpenMP (openmp.org) for c
  • threading building block (threadingbuildingblocks.org) for c++

最後他提到了MPI(Message Passing Interface) http://www.mpi-forum.org/, 目前的multi-core 是以shared memory為前提, 我在想既然現在memory這麼便宜, 或許我每個core都讓他有自己獨立的memory (4G?), 然後全部以message passing來做, 不知道這樣的架構可不可行XD

[Erlang] short summary (part 2)

上次大概介紹了Erlang這個語言的特性, 這次我想稍微介紹一下OTP的設計概念或者說我們應該要怎麼用Erlang來設計network service。(需要稍微了解Erlang 語法), (p.s 本篇code跟圖出處都是Joe的論文)

Erlang的OTP設計上,他是把關於concurrent programming隱藏起來,讓使用者只需要專注於sequencial programming的部分,現在我們來看它是怎麼實作的。

OTP也是使用client-server的架構, 所謂client-server就是指以下這張圖

image

最基本的generic server code如下:

-module(server1).
-export([start/3, stop/1, rpc/2]).
start(Name, F, State) –>
 % register and create a process which name is Name
 % and tell the server to use the handler function F
 register(Name, spawn(fun() ->
        loop(Name, F, State)
        end)). 
stop(Name) -> Name ! stop. 
rpc(Name, Query) –>
  % send the message to server Name
  Name ! {self(), Query},
  receive
        {Name, Reply} -> Reply
  end.
loop(Name, F, State) ->
   receive
         stop -> void;
         {Pid, Query} –>
               % important!! use function F to compute message
               {Reply, State1} = F(Query, State),
               % and return the message to client
               Pid ! {Name, Reply},
               loop(Name, F, State1)
end.

以上的程式流程大概是這樣跑:
註冊新的process當server, 告訴它使用的handler, 此process一直在function loop中wait message, 它會接收到兩種message, 一種是stop, 那server就會停止,另一種傳Query, 讓server利用Query去做事, 然後再回傳結果給client Pid, 並且更新server自己的狀態

有了以上的generic server model, 我們現在就可以實際針對我們所要開發的server了!

假設今天只是要做個簡單的Home Location Register

-module(vshlr1).
-export([start/0, stop/0, handle_event/2, i_am_at/2, find/1]). 
-import (server1, [start/3, stop/1, rpc/2]).
-import(dict, [new/0, store/3, find/2]). 
start() –> start(vshlr, fun handle_event/2, new()). 
stop() –> stop(vshlr). 
% server’s api
i_am_at(Who) –> rpc(vshlr, {i_am_at, Who, Where}).
find(Who) –> rpc(vshlr, {find, Who}). 
% event_handler
handle_event({i_am_at, Who, Where}, Dict) –>

    { ok, store(Who, Where, Dict)};
handle_event({find, Who}, Dict) –>

    {find(Who, Dict), Dict).

所以我們只要實做出自己的handler就可以產生一個簡單的

所以在Erlang的virtual machine下, 我們就可以這樣做

1> vshlr1:start().
true
2> vshlr1:find(“joe”).
error
3> vshlr1:i_am_at(“joe”,”sics”).
ack
4> vshlr1:find(“joe”).
{ok,”sics”}

上面的例子中, 我們可以看到對於用Erlang來實作出一個簡單的server是如此的簡單, 但是我們還沒有提到關於error recovery跟runtime upgrade的部分, 以下就這兩個部分來說明

Error recovery:

首先修改我們的server code

rpc(Name, Query) –>
    % send the message to server Name
    Name ! {self(), Query},
    receive
           {Name, Reply} –> Reply ;
           {Name, crash} –> exit(rpc)
   after 10000 –>
           exit(timeout)
end.
loop(Name, F, State) ->
       receive
          stop -> void;
          {From, Query} –>
                case (catch F(Query, State)) of
                    {‘EXIT’, Why} –>
                        log_error(Name, Query, Why),
                        From ! { Name, crash},
                        loop(Name, F, State);
                   {Reply, State1} –>
                       From !{Name, ok, Reply},
                       loop(Name, F, State1)
                  end
  end.
log_error(Name, Query, Why) –>
% something you can log

所以當有錯誤發生的時候, 我們就直接把錯誤log下來, 並且告訴client, 關掉client, 而且我們設置了一個timeout, 當client等待太久, 也會關掉

接下來我們接著改成可以runtime code replacement的版本

swap_code(Name, F) –> rpc(Name, {swap_code, F}).
loop(Name, F, State) ->
     receive
           stop -> void;
          {From, {swap_code, F1}} –>
                From ! { Name, ok, ack},
                loop(Name, F1, State);
          {From, Query} –>
               case (catch F(Query, State)) of
                    {‘EXIT’, Why} –>
                        log_error(Name, Query, Why),
                        From ! { Name, crash},
                        loop(Name, F, State);
                  {Reply, State1} –>
                        From !{Name, ok, Reply},
                        loop(Name, F, State1)
            end 
  end.

一切都是如此的簡單容易, 當然真正的OTP不是那麼簡單的, 不過這邊我只大概說明OTP設計的概念, 還有Erlang在設計這類程式的方便性, OTP裡面還有關於supervisor等課題沒介紹,而且關於效率上跟實務上的應用我本身也不熟(剛開始接觸而已^^””), 接下來我準備開始實際去trace Erlang的source code, 看底層的實作關於message passing跟light weight process, 所以可能會拖很久才會繼續寫下去吧XD

Reference: Making reliable distributed systems in the presence of software errors