2009年12月24日 星期四

CUDA新書到


Bee之前都是自己收集資料,看原文去理解。所以差不多是遇到什麼再去查。
終於有本比較集中資料的書了。常用的運算法也都有解釋。雖然Bee也查的差不多了。
不過買了除了自己查外,拿來教人也是真的。
隨著CUDA運算的流行,實驗室影像組的CUDA人員正在擴張中。

除了影像運算外,Bee本身就是控制組的人,也很想用到Robot控制上。
其中最大的原因是GPGPU的價格低到可以和影像處理的DSP差不多了。
一台使用Atom+ION的NetPC也很合適於控制Robot。
看看控制組何時也想用用CUDA了。

2009年12月16日 星期三

acer小主機


Bee因為有使用P2P下載軟體,使用四核心電腦來用實在有點耗電,所以買了atom處理器的小主機,價格為7xxx元。
不過因為有之前買筆電的經驗,所以決定買具有獨立顯示晶片的機種。
其實能選的不多,只能選用ION晶片。
最後買了acer小主機。
後來才和同事的小筆電比一下效能。
以atom來說是差不了太多。都可以很順的跑Office。
但玩Facebook就不一樣了。
ION晶片可以處理四個Facebook網頁,小筆電第二頁就不太行了。
可見獨立顯示晶片對於現代電腦的重要性。
當時同事說小筆電只是上網及打報告,結果Facebook流行起來,又不行了。

不過當時拿到公司去安裝作業系統時,發現小主機跑得比公司給我的電腦快。
CPU等級沒有比較好,但RAM及HDD都是比較快的,所以整體表現就比較好。
所以拿公司電腦去做PCI卡上的FPGA程式開發是對的,讓它早死早超生吧!


看"遊戲編程精粹6"心得


這篇不太能稱得上是心得。
主要是驚訝於2006年的書,已經預測了2009年Bee所使用的技術。
Bee目前有用到的且書上提到的有:
OpenMP,
OpenCV,
Lua,
GPU,
人工智慧

可見得遊戲上所使用的軟體技術是相當先進的。目前才在Bee的使用上開花結果。
但Bee更相信所謂的專家,真的有預測正確,只是有多少人看出來並願意去相信。
早個一二年去相信,也許整個狀況將大不相同了。

2009年參賽獎狀




假共享(False Sharing)問題

在看CUDA Programming Guide時,有一大篇討論Shared Memory Access Patterns with Bank Conflicts問題。這個一直不太了解。

後來找多核心文章,發現假共享(False Sharing)問題。仔細看,這個不就是CUDA裏面提的問題。
由此Bee之前推測的CUDA中的Share memory是軟體管理的cache,這個論點是確認無誤了。因為使用一樣的硬體,才會有一樣的問題,連解法都一樣。

好在之前沒有將share memory做為寫入用,所以問題不大。
之後要小心考量使用share memory的寫入問題了。


2009年12月13日 星期日

CUDA計算積分數列的方法

使用平行運算計算總和,還可以理解。但要算積分,不符合平行運算的方法,這下要如何?
積分數列的數學問題是這樣的:
數列 X=[ a0 a1 a2 ... aN ]
要算出 Y=[ a0 a0+a1 a0+a1+a2 ... a0+a1+a2+...+aN ]

其實有注意到的人會發現,為何這個問題Bee要用平行運算。因為這就是圖像積分法(integral image)的基本運算。因為要移進GPGPU來做,問題就來了。
因為每一個數列元素要等上一個元素的值出現才能算,可是平行運算要沒有相關才能用,這下子有解嗎?
找了許多文章,一張圖解了這個問題。

果然還是因為沒有收集平行運算的演算法,才會不知道往那裡去找。
找到了之後,發現這個動作可以做以下的計算:
Radix sort
Quicksort
String comparison
Lexical analysis
Stream compaction
Sparse matrices
Polynomial evaluation
Solving recurrences
Tree operations
Histograms
看來是很重要的演算法,值得好好去了解。


2009年12月12日 星期六

CPU和GPU的合作,和大腦分工相似。

Bee是搞自動控制的,有一個問題一直是系統不好選擇的。到底是要用分散式處理器來做系統運算,還是用PC做中央控制。
分散控制也是有好處的,系統加元件是很快,因為關係單純,但程式不好改,要改許多處理器程式。
中央控制則是要經過中央管理系統,比較複雜,但程式好改。

這個問題到Bee開始處理影像相關問題,才知道要如何選。
原因在於影像處理無法使用分散運算的方式,若是真的要用,那訊息傳輸系統一定一直在傳影像相關資料,反而是一種浪費。

不過一開始Bee處理影像控制是想用FPGA來做,但它的記憶體不足,必須外掛SDRAM。
規劃到一半GPGPU興起,完全符合影像處理的需求,我就直接轉到GPGPU的領域去。
其實對於影像處理,其瓶頸在於運算相同,但資料量很大,平行計算才能有效解決。
但資料之間有相關,無法分開存放,要使用集中式的存放才能有效運算。

只是理解之後,Bee在想,一樣的工程問題,生物界是如何解的?
果然,大腦的發展,差不多和眼睛的出現是相關的。不是一個感光細胞的眼睛,是一群感光細胞組成的眼睛。

Sensor Array的出現,就是引入大量平行處理的開始。
在multi-sensor的狀況下,腦不需很大,大概就處理環境記憶和時間相關資訊。
但Sensor Array就不同了,記憶體需求量大,且運算力大增,才可做出分析。

在玩CUDA之後,發現並非所有的問題都合適GPU運算。在做統合判定的地方,CPU的運算更合適。
而且CUDA的異質運算結構,可以比OpenMP更容易去選擇運算結構。簡單的說何時要用CPU運算,何時要做GPU運算,是很容易分的。
但OpenMP不是如此明顯,但還是有平行運算的味道在。

最近看了"你腦內的兩個世界"
http://blog.xuite.net/unlimiter1001/unlimiter/29032221
了解兩個半腦的分工,更可以確定人工智能真的需要並行處理器及串行處理器的配合。
腦之所以二個完全分開,正因為腦的運算為成長型。右腦專精於平行處理,左腦專精於串行處理。二種迴路基本型式必然完全不同,所以分成二個腦來成長。
也可以說生物界對於平行運算和串行運算,沒有做出統一的解,所以長出二個處理器來做。
那Intel想用X86來做GPU,想必無法有效和真正的GPU來競爭。果不其然Larrabee的計劃真的失敗。

但並行運算就算是解了影像處理問題,但後繼串行處理的部分也是會增加運算量。原因是資訊也跟著變多,串行處理的資料及儲存也是要跟著增加上去。
所以左右腦的大小一直都是一樣,可見得二者重要性誰也沒有贏過誰。
意指,就算CPU和GPU就算合成一個晶片來做通用運算,二者電路的比例可能仍是很相近。那關於這個預測,要等GPGPU運算普及才會有人探討。

那對於現在,Bee的問題出在沒有收集過平行運算的運算法。因為才開始流行,資料不多。但對於軟體發展,這是無法避免的。
只能開始注意及了解相關的發展了。



2009年12月9日 星期三

使用積分影像法(integral image)取代金字塔圖層




做影像處理常用到金字塔圖層的方式做影像加速處理的方法。
但金字塔圖層會多用掉記憶體,使用量剛好是原圖的一半。
後來發現有人使用積分影像法(integral image),它可以同時代表原圖及金字塔圖層。
因為可以做不同大小的差分而獲得所需的圖。
只要取點時算A-B-C+D就好了。



2009年12月8日 星期二

如何將影像處理程式改寫為CUDA程式

這裡提出我遇到問題時找到的原則:

1.保留原程式結構,先找出最多層for的地方,先將這個函式GPU化。

2.找出要GPU化的函式所要的輸入及輸出資料。從個別處理改為表格化資料,因為要展成並行處理。

3.找出各for對應的並行層。
  就是將各for展成threadIdx及BlockIdx。
  和圖檔長寬相關的for主要以BlockId.x及BlockId.y做分配。因為這二個系統變數可用範圍最大。

4.先產生CPU可執行函式取代,用以分離函式準備GPU化。但可以驗證及除錯。

5.驗證成功後,GPU化的程式再試。

6.針對GPU結構開始最佳化。在CPU的GPU版本上做除錯及驗證。

7.完成關鍵的CPU轉GPU函式,再找需要做的部分進行合併。

實際上執行仍有許多問題要克服,解決了再整理。

2009年12月4日 星期五

CUDA工作排程的了解


寫了一點CUDA程式,但對於寫出最佳程式並沒有什麼好辦法去了解,難到只有實測一途了嗎?
當然不是,可以找一下CUDA SDK中有一個試算表CUDA_Occupancy_calculator.xls。
玩了試算表,就可以稍為了解CUDA指令排程,其實和發動的執行時所使用資源有關。

可以發現只有三項資源可以調整。
1. 每一個Block使用多少Threads
2. 每一個Thread使用多少Registers
3. 每一個Block使用多少Shared memory

使用CUDA寫程式時對於每一個Block使用多少資源是很明確的,但對於每一個Thraeds使用多少Registers則不是可以直接得到。
不過調整一下數值可以發現CUDA的排程限制。

從文件可以知道一次CUDA指令可以有32個核心動作,這個叫Wraps。在不同核心架構下一次可以發動的Wraps數目不同。
因為工作上是以Block為主要規劃,所以Threads的數目除以32就是Wraps數。
像Bee用的G9600M最大的Wraps數目是24,24是不太好的數字,因為Bee寫的程式動作大部分和2的倍數有關,所以常常無法有效使用。

但不是可以使用的Threads多,Wraps數目就會多,因為因為每一個Threads都是一個core task會用掉Registers。對每一個multiprocessor來說,Registers數目是有限的。
所以就會有Registers總數限制,就是第二項要控制的。

通常一個Block會有共有的變數,此時就要使用到Shared memory,這項資源為每一個multiprocessor才有,所以又變成另一個限制。
由此可以看到一件事,雖然一個multiprocessor有八個core,但可以執行的Threads數目不是八。
可能Threads數目是32,八個core要分成四次執行。
另一種可能是因資源用完,32個Threads是分成4個multiprocessor去做。
若是資源使用很多,有可能每一個multiprocessor只能使用4 core,這時1個wraps會佔用更多的multiprocessor。

可以見得使用比較好的顯卡,因為Multiprocessor多,所以可以解比較耗資源的threads task。
以上為玩試算表所得的心得,實際上可能要實驗才能證實。

玩過後,發現程式工作如果分得比較細小的程式段,會有助於執行分配。
但要分到多細小,真的就要用這個試算表下去估了。

2009年11月30日 星期一

如何了解__syncthread()的使用時機:試誤法

在使用CUDA shared memory常會使用__syncthread()來避免資料不同步處理造成的破壞。問題是一般人無法判定何時會產生這個問題,所以會先加以做為保險。

可是加了之後確實會影響執行速度,Bee這邊測到的就差了四倍多。
所以要適當加入__syncthread()才是合理。

剛好之前bee使用CPU及GPU同時開發程式的方法,因為一邊為single-thread另一個為multi-thread,所以可以保證single-thread是正確的。剛好可以比對結果。

若是不加__syncthread()會使結果比對產生錯誤,那就要加。沒有錯誤就照CPU版本的直接移入GPU版本。

這種情況玩個幾次,基本上就可以知道何時要加,何時不要加。


2009年11月19日 星期四

第二個CUDA程式,使用Shared memory

因為有共同讀取的來源資料,所以先行載入shared memory。然後經過運算,之後回存。
因為Windows下的CUDA沒有除錯器,所以先發展CPU下可以執行的GPU架構程式。先將變數之間的關係弄清楚再移進GPU。
至於shared memory也是一種區域性變數,所以用local variable來模擬。

CPU版本程式:
void CPU_mask_rotate(unsigned int *src, unsigned int *dest, int gridDim_x, int gridDim_y)
{
    unsigned int idata[HEAD_LENGTH];

    for(int blockIdx_y=0; blockIdx_y < gridDim_y ; blockIdx_y++){
        for(int blockIdx_x=0; blockIdx_x < gridDim_x; blockIdx_x++){
            // Read to local var.
            for(int i=0; i<HEAD_LENGTH; i++){
                int t = (blockIdx_y*HEAD_LENGTH+i)*gridDim_x + blockIdx_x;
                idata[i] = src[t];
            }
            // convert format
            for(int threadIdx_x=0; threadIdx_x<TRANSPOSE_SIZE; threadIdx_x++){
                for(int j=0; j<HEAD_BLOCK; j++){
                    unsigned int r;
                    r=0;
                    for(int k=0; k<TRANSPOSE_SIZE; k++){
                        unsigned int u,v;
                        u = idata[j*TRANSPOSE_SIZE + k];
                        v = (u>>threadIdx_x & 0x1)<<k;
                        r |= v;
                    }
                    int t = (blockIdx_y * gridDim_x + blockIdx_x)*HEAD_LENGTH + threadIdx_x*HEAD_BLOCK + j;
                    dest[t] = r;
                }
            }
        }
    }
}

GPU版本程式
__global__ void Kernelmask_rotate(unsigned int *src, unsigned int *dest)
{
    __shared__ unsigned int idata[HEAD_LENGTH];

    for(int i=0; i<HEAD_LENGTH; i++){
        int t = (blockIdx.y * HEAD_LENGTH+i)*gridDim.x + blockIdx.x;
        idata[i] = src[t];
    }
    __syncthreads();

    for(int j=0; j<HEAD_BLOCK; j++){
        unsigned int r;
        r=0;
        for(int k=0; k<TRANSPOSE_SIZE; k++){
            unsigned int u,v;
            u = idata[j*TRANSPOSE_SIZE + k];
            v = (u>>threadIdx.x & 0x1)<<k;
            r |= v;
        }
        int t = (blockIdx.y * gridDim.x + blockIdx.x)*HEAD_LENGTH + threadIdx.x*HEAD_BLOCK + j;
        dest[t] = r;
    }
}

CPU寫好時,就改一下變數名( _改為. )就可以copy到GPU的版本。

只是在發展中發現一個奇怪現象。
因為讀入shared memory可以使各thread少去對global memory的讀取,而減少執行時間。
但在寫程式的時候,去算各位址不好判定,所以先用一塊shared memory存結果,再從shared memory存回global memory,因為這樣比較好寫。
後來發現CUDA SDK內的example都是直接回存。這樣可以省去shared memory,不過就是不好寫。


2009年11月6日 星期五

3D Webcam


想當時比CUDA比賽時,為了做webcam解3D。花了時間及錢去買二個Webcam。

結果二個獨立webcam有很多問題。包括顏色不相同,雜訊狀況也不一樣。又要解決不平行問題,結果每次都要進行調整。

不久前看到3D webcam才覺得有點做白工,3D Webcam不見得二個webcam狀況完全相同,但差異性小了許多,且機構的關係是固定的。

一個USB線同時可以進行二個webcam的影像傳輸。不會一次用掉二個USB。

另外還可以用紅藍眼鏡玩玩3D影像。
有了這個,以後要自己試用CUDA解3D要方便多了。


2009年10月28日 星期三

CUDA程式開發軟硬體環境

找好放起來,可以做為後面開發之參考資料。和別人討論也會有個依據。
Bee是使用筆電為主要開發環境,主因是便於攜帶展示。

機種:ASUS M50Vm
CPU: Intel Pentium Dual CPU T3400 @2.16GHz
RAM: DDR2 667 2G*2
O.S. : Windows XP Sp3
VGA : nVidia GeForce 9600M GS, 1G RAM
CUDA Driver: cudadriver_2.2_winxp_32_185.85_notebook

開發環境:Visual Studio 2008 Professional版
函式庫:OpenCV_1.1pre1a

以下為CUDA SDK中測得之系統環境參數:





2009年10月15日 星期四

為何使用CUDA

其實我本來想學平行處理語言是用Erlang。在做論文相關研究時,是要用FPGA+DSP去解電腦視覺上的問題。

結果在找資料時意外發現GPGPU也可以做。而GPGPU中就以CUDA最為完整。
使用CUDA在程式上並不麻煩,環境不好架是真的。不過為了可以在學校也可以展示,所以將自己的筆電換成可以執行CUDA的獨立顯卡的筆電。

沒想到換筆電並沒有解決我的問題,反而產生新的問題。
首先是Vista作業系統的問題,界面非常不習慣。而且也有許多語言無法安裝。這對程式設計師來說是不能接受的。
玩了二個多星期,剛好ASUS也出了XP的驅動程式安裝說明,我二話不說就直接換了。
再來是CUDA的驅動程式,沒想到我買的筆電原本是沒有的,這下我不是賠大了。要不是Vista搞鬼,我一直沒發現。
運氣很好的是,在我換成XP後沒二天,給筆電用的CUDA驅動程式也出了。好家在。

終於在買下筆電後一個月開始進軍CUDA。但已經離CUDA程式設計比賽報名截止已經不久了。心想還是去報名一下好了,就這樣正式用了。
比賽結果還不錯,買筆電的錢回來了快一半。

另一方面,學校教授也想用,我因為比賽的關係進度比日間部的快。
現在於CUDA上相關的程式開發我成了重要角色,這是我原先沒有想到的。

在使用CUDA上面,其實筆電是很不合適的。因為為了省電,GPU核心數目都不多。
不過我的筆電有點特別,不僅有32核心,也配有1GB的VRAM記憶體,價格上很平價。執行CUDA運作算順的。
在和其他日間部研究生的筆電比起來,我的筆電跑CUDA算是跑的很快的。只是我這款筆電也已經停產了,他們想換也沒法度了。

現在我的論文就要靠CUDA了。使用GPGPU目前對於自動控制而言是很新的。再來就看要做什麼畢業了。

2009年9月17日 星期四

LCM當機解法

最近收到LCM當機客訴。說會當機,經大陸工廠實測,機器連續運作200次會發生3次當機,但有的機器不會。


因為就是用我做的簡單多工,我自然必須去追。


問題是,當機率不高,實在不好抓。而且研發部只有一台機器,實在不容易做為代表。


我實在查不出那裡有問題,因為好像只有一個Task當,其他Task沒當掉。


所以只好在通訊解析上做了一個Buffer邊界檢查,然後請大陸工廠測。


結果很不錯,都沒當機。


這樣可以確定是通信品質有問題。


MCU的程式,果然是一點可能發生錯誤的可能性都不行,因為實在不知電子是否有穩定。





2009年9月11日 星期五

找質數

function prime(max_value)


    local value = 5;


    local index = 2;


    local root_index = 2;


    local limit = value * value;


    local p = {};


--  local count = 0;


--  initial first value start at 5


    p[1]=2;


    p[2]=3;


--  start find prime


    while value <= max_value do


        local sub_index=2;


        local check_not_prime = 0;


        while sub_index <= root_index do


--          count = count + 1; print(count,value,limit,index,sub_index,p[sub_index]);


        if (value % p[sub_index]) == 0 then check_not_prime = 1; break; end


            sub_index = sub_index + 1;


        end


        if check_not_prime == 0 then


          index = index + 1;


          p[index] = value;


        end


        value = value + 2;


        if( value >= limit ) then


            root_index = root_index + 1;


            limit = p[root_index+1] * p[root_index+1];


        end


    end


-- print all prime


    for i,j in pairs(p) do


        print(i,j);


    end


end


 


-- test


prime(100);


 


-- 程式結束


 


結果使用矩陣p{}儲存,所以要知道目前已有多少數目以index記錄。


已知只要找到現在驗證值value的開根以下的質數做驗證,所以加入root_index告知。


而現值超過上次有效質數平方limit,則要再更新。


2009年8月18日 星期二

指標的藝術,讀後感



書名:指標的藝術,程式設計最絢麗的星星

作者:蔡明志

出版:碁峰

日期:2009.07

 

這本書吸引我的是,中文很少有專門探討指標的進階書。

但就目錄上來看,我才發現原先以為沒有指標的電腦語言竟也出現在內。

因為我本來就熟C也很清楚學會了,幾乎就等同掌控其語言的控制能力。

不過另一點的是,作者"蔡明志"之前出的書也很不錯。之前出資料結構及C語言的書都寫得不錯。

書可以看到的語言有CC++C++/CLRJavaC#Visual BASIC

那一本書看完了,不就一次會六種語言的核心了,我是這樣想。而且只需安裝Visual StudioJava二套軟體就可以玩了。

 

就書內容結構來看,仍以C語言的篇幅最大。這也是合理,因為除了C++其他語言無明顯指標。

內容以每一種語言皆使用同一種資料結構的表示法來示範如何寫。

本以為進階書會提出更深入的內容,但沒有,只是示範最基本的資料結構。大幅度的將難度降低了。

其實我覺得這樣做是合理的,因為進階書本來就不好賣,太深入恐怕讀者更少,降低難度有助於推廣。

 

對於想在程式上有進階參考的工程師,我認為這仍是一本值得看的書。

而指標已經熟悉的人,看了此書也可以一次通曉六種語言,仍是值得買來參考的。

2009年8月17日 星期一

CUDA程式設計比賽

參加nVidia舉辦GPU程式設計比賽。
http://www.nvidia.com.tw/object/cuda_contest_main_tw.html

2009年8月10日 星期一

立體視覺計算

這是之前專題的照片。主要是解雙目視覺。因為現在已改成由GPGPU來做了,就將以前實驗的成果張貼一下。
之前用Matlab做的,計算時間很久。當時只是驗證可行性。

實驗環境:


左眼照片:


右眼照片:


視差計算結果:

立體圖:

uCOS-II Win32 Port解析及改善 -- 3

Win32 port運作原理解析:


基本原理是使用WindowsThread機制來做為uCOS-IITask管理。但實際上有許多細節要處理。一般要移植有幾件事要處理。


1.    Critical Section方法選擇


2.    Context Switch的方法


3.    InterruptTimer Interrupt處理


在移植到CPU時,因CPU的特性有一定行為,可以找出對應方法。


但在作業系統上做移植,仍要處理,但面對的行為不同,所要處理方式變得完全不同。


在使用作業系統的Thread做為管理時,所要考量的項目及目標為:


1.    Context Switch的方法:因為己非CPU動作,所以此項行為要借用被寄生作業系統的既有動作。在此次porting是使用Event觸發的方式做,借由另一個優先權最高的排程器程式來執行,而Context Switch真正工作已由被寄生作業完成,只剩下排程。而排程不可能由Task來執行,因為Thread只可以被suspendresume,中間無法插入其他程式去執行,故必須產生一個獨立的Thread來執行。


2.    Interrupt方法:由被寄生作業系統的Event觸發執行的Thread來做,也會使用排程器,另外加上UserInterrupt hook


3.    Critical Section設定:只需關閉寄生作業系統所使用的Event就可以做到。


4.    Idle Task的方法:在CPU時會跑計數器,但在寄生則要加上Sleep(),將工作權還給被寄生作業系統。


依函式名稱有修改的列表為:


OSCtxSw(void)


OSIntCtxSw(void)


OSStartHighRdy(void)


OSTaskIdleHook()


OSTimeTickInit(void)


OSTaskStkInit(...)


OSTCBInitHook(OS_TCB * pTcb)


OSInitHookBegin()


以上皆為使用原先的功能及Hook功能加載來加入所需處理程序。


四種重要的函式為


OSEnableInterruptFlag(void)


OSDisableInterruptFlag(void)


OSScheduleThread(INT32U param)


OSInterruptThread(INT32U param)




前二個函式為Critical Section所使用。後面二個為Thread程式本身,也是此porting關鍵之所在。而使用二個獨立的Thread來做為ScheduleInterrupt的工作是在CPU移植上不會見到。可以若以多重CPU的系統來說,這反而是更為合理的做法,因為在CPU數量無限的狀況下,O.S. context switch是浪費時間的,而由另一個CPU做排程會是更好的方法。經由了解二個額外的Thread可以更清楚的了解在Win32 port的工作內容。




OSScheduleThread(INT32U param)主要工作是承接由OSCtxSw(void)呼叫之後的工作。故此Thread就必須擁有最高的執行優先權,由Win32API的行程同步函式WaitForSingleObject()做為其等待的函式。在等到有觸發產生執行時先以維護uC/OS-II應做的事,最後再以SuspendThread()ResumeThread()此二個Win32API函式做為uCOS-II中的Task切換的工作的控制。在此並不像切換,反倒是更像開關。而所有的Task必須在Win32API下註冊為一獨立的Thread才可以正常運作。在Win32 port中以hTaskThread[]變數做為ThreadHandle存放矩陣,對應數目和TCB相同。故可以看到在處理TCB時也必須修改。但在OS_TaskChangePrio()因無Hook函式可以用,因而無法使用。




OSInterruptThread(INT32U param)工作內容較為簡單,在Win32 port中主要是模擬出八個中斷給uC/OS-II用,除了interrupt 0是保留給Timer用,其餘皆為使用者定義。使用Win32APIWaitForMultiObjects()為其等待函式,hInterruptEvent[]變數則為存放Event Handle的地方。Win32APIEvent在使用後必須呼叫ResetEvent()Event做清除動作。而User Interrupt function則存放於interruptTable[n]()函式指標矩陣中。




由以上解析可知,在Windows端使用到的函式為


OpenEvent()


SetEvent()


WaitForSingleObject()


WaitForMultiObjects()


setTimeEvent()


ResetEvent()


可以查Win 32A PI中對於這些函式的使用方式就可以了解寄生及被寄生作業系統之間的相關性。


uCOS-II Win32 Port解析及改善 -- 2


使用Win32 port實作:

此次實作環境為:

Windows XP作業系統

uC/OS v2.80

Borland C++ Builder 6.0

 

uC/OS中的檔案修改如下:

CPU相關的檔案有

OS_CPU.H

OS_CPU_C.C

此二個檔案必須更換為Win32 port用的檔案。而原先必須使用組合語言的OS_CPU_A.ASM則未使用,原因是使用的是高階呼叫,故不需要,而在此檔案內的功能則由OS_CPU_C.C取代。

PC介面相關的檔案為

PC.H

PC.C

則也必須更換為Win32 port下使用的版本。

C++ Builder中則是以Console Applications為程式行為主體。所以可以知道程式只有一個進入點main(),和原先CPU的單工環境相類似。

先利用原作者提供之Example檔案建造執行檔,看有無其他問題。但部分程式碼仍會產生一些Warning,主要是原型宣告在不同的Compiler下有些不同,經稍為修飾後即可執行。其畫面如下:

原始碼有提供使用外部中斷的程式,一樣使用C++ Builder重建,在執行後可以改變Example的輸出結果,可以證明確實可以使用另一程式對Win32 port的程式產生中斷觸發的動作。結果如下:


因為並非常用此Example做為開發用。故以原始的Example #2為例修改並編譯,發現原始碼中有許多為DOS專用程式碼,必須刪除。但為了維持其可移植性,改使用巨集調整的方式做為不同平台之間原始碼調整用。在Win32 port中可以找到一些特有巨集定義在使用Windows時,以”__WIN32__”巨集可以使用。

相關的修改包括有:

DOS中斷設定及回復:在Win32中不需要。

程式結束的處理:在Win32中處理的函式不同。

浮點運算器的處理:在Win32中不使用模擬浮點相關設定。

在設定好了巨集切換後,可以執行的畫面如下:


可以看出外型雖然有像DOS版本程式,但仍有許多不一樣的地方。

1.    Free Stack的大小,呈現完全沒有使用的狀態。原因是Task StackWin32下是由作業系統安排,人工配置Stack並不會使用。但為了維持和DOS相同的程式碼,仍配置Stack用記憶體。

2.    最下面一行的閃爍字元並不閃爍,這是因為PC.C中的Win 32A PI中的Console控制並沒有設定閃爍字元。但不影響主要功能。

3.    螢幕大小是可以縮放,所以右側多了滑動棒。DOS是固定25*80字元,而Win32 port無此限定。在使用Printf()函式時,可以保留更多的資訊。

4.    Windows上面CPU使用率維持不超過10%,因為使用WindowsSleep(),相對於uC/OS上的CPU使用率是不準的。




uCOS-II Win32 Port解析及改善 -- 1

摘要:


uCOS-II移植到Win 32A PI函式下,使之成為寄生在Win 32A PI下的作業系統。並改進和外部通信的部分,增加可使用能力。對於桯式邏輯除錯及模擬上有較佳支援。


 


介紹:


了解uCOS-II作業系統結構和Windows作業系統中的行程管理函式,經由移植的方式增加作業系統之了解。在此移植中要實現的功能有:


1.        uCOS-II中斷模擬。


2.        WindowsuCOS-II資料傳輸通道連接。


一般在學習uCOS-II會在Windows下使用DOS模式來學習,但純DOS程式在Windows下會很消耗CPU使用率,在使用Windows port程式則使用Windows管理則不會消耗CPU使用率,而且可以使用一般Windows的程式除錯器,對於程式邏輯的除錯效率上可以發揮很大的功用。


uC/OS Win32 port主要是採用Werner.Zimmermann的版本為主。採用此版本的主要原因是原作者只利用到原始uC/OS程式碼中的hook功能,不去更動作業系統中的程式碼,如此可以保有在各處理器及各版本之間的相容性。而且在各版本的uC/OS Windows port中亦為有在維護在最新狀況下的版本。不只可以在Windows下執行,亦可以在Linux中實現,足可見此版本的移植力甚強。故以此版本為其基礎,探討其運作原理及加入模擬所需之改進。但此版本目前仍有部分功能並不是完全做到,第一點是即時性,因為是寄生,所以無法做超越基礎作業系統的能力;第二點是限定無法使用OS_TaskChangePrio()


在其他版本則有其功能不全,故未予以採用。以下簡介不採用原因:


www.micrium.com 中有使用Win32 Thread的版本,此版本並沒有支援uC/OS中斷的能力,所以無法有效使用其版本。


http://wsim.pc.cz 亦有uC/OS win32 port,但其uC/OS版本在2.00版本,必須使用其專用模擬器,且版本亦沒有維護,恐與後面版本產生不相容現象,故亦不予採用。


2009年7月5日 星期日

平行計算介紹(草稿)

因為要報告,所以整理了一下我所了解的平行計算。簡報內容如下:
===========================
平行計算介紹
0.介紹
  多組數據或任務同時作業的計算方式

1.平行計算分類
  a.平行型式
    1.位元並行處理Bit-level parallelism
      8 bit -> 16 bit -> 32 bit -> 64 bit
      由增加同時計算之位元數來達成加速資料處理
    2.指令並行處理Instruction-level parallelism
      Pipeline
      Superscale
    3.資料並行處理Data parallelism
      Single Instruction Multiple Data(SIMD)
      PC:MMX,SSE,3D Now
    4.任務並行處理Task parallelism
      function parallelism
      control parallelism
  b.硬體實現:並行電腦
    1.多核心Multicore computing
    2.對稱多處理器Symmetric multiprocessing
    3.分散式運算Distributed computing
      a.大型平行處理器Massive parallel processing
      b.叢集運算Cluster computing
      c.網格運算Grid computing
  c.硬體實現:特殊電腦
    1.Reconfigurable computing with field-programmable gate arrays(FPGA)
    2.Scalable Embedded Array Processor
    3.Vector processors
    4.General-purpose computing on graphics processing units (GPGPU)
      SIMT
    5.Application-specific integrated circuits(ASIC)
   
2.平行計算軟體方法
  a.Multi-Process
  b.Multi-Thread
  c.OpenMP
  d.Erlang
  e.OpenCL、CUDA
  f.VHDL、Verilog
 
3.平行計算的使用場合
  a.電腦模擬及預測
    天氣預報
    電磁波
    機構
    電子
  b.電腦影像處理
    照片
    影片
    3D-Game
  c.感測器矩陣Sensor Array
    天文望遠鏡
    大型強子對撞器
    CCD
  d.特殊應用
    非破壞性檢測
    醫療領域
 
4.即時平行計算
  a.應用領域
    醫療
    視覺檢測
    On-line-Game Server
    電腦影像處理應用:大型印表機
  b.因成本降低,現在可以採用
    a.Multicore
      1.成本低
      2.軟體變動小,可以套用在原有程式上
      3.效率提升和核心數成比例
      4.仍受限於其它資源的效能
    b.GPGPU
      1.成本低
      2.軟體變動中等,但寫法不同會有很大的效能差異
        要了解GPGPU內部結構
      3.只有資料無緊密關係時才有加速力
        矩陣運算
        影像處理
        可達100-250倍CPU運算量
      4.高資料流頻寬
      5.有回傳問題
        GPGPU記憶體是獨立的
    c.FPGA
      1.成本中低,需電子能力
      2.獨立於PC運作,使用PC界面連接
      3.除錯變成和電子系統混合,難度較高
      4.即時性極高,但運算格式受限
        整數系統很好,浮點數不好
5.結論
  人類慾望無止盡。
  硬體成本下降。
  電腦應用的普及化。
  原先的先進技術,將會平民化。
  舊技術因成本下降,會造就新市場。
=======================
剛好學了FPGA加上現在的CUDA,所以實現有望了。


2009年6月19日 星期五

突然發現自己走上另一條路

因為公司一直沒有成長,也待了六年。為了排解工作上的不得志,於是去讀夜校,讀有興趣的技術。
最近發現,技術開始有結果,但並不是公司可用的技術。
為了有好的薪資,結果可能要另找出路。
但公司上司不錯,只是有個不長進的CEO。
無奈!終有一天是會離開的。

因為不長進的CEO,讓我得了四關。
不想見:從未有好臉色,遇到只會問進度,開會只會罵。
不想聽:決策快但沒有品質,只會搶功,朝令夕改,與其聽命令不如等他改。
不想講:任何事都是他對,不說反而有空間去自己處理到好。
心灰意冷:如果真的有績效就好了,但六年來只是看到重覆的戲碼。而且招式越來越沒品。

唉!我又不是不想對公司盡力,想當初也是想做技術而來。只是無法發揮乃因政治因素。
到了心灰意冷時,總要找個出路才行,做非公司技術做久了也是會有結果的。
那再下來又會如何?
我想不出第二個結果。


2009年6月16日 星期二

論文要做什麼呢?

最近同學們畢業了,我則還沒有想要做什麼論文。

看來還是做機器視覺好了。

所以就以CUDA做機器視覺加速。

不過PC上開發軟體沒有那樣熟,我可能要使用到OpenGL及OpenCV。

所以整個工具組要用到Visual Studio 2008、CUDA、OpenGL及OpenCV。全都是沒有用過的,看來挑戰大了。


2009年4月2日 星期四

使用加法做開根及平方計算

主題:使用加法做開根及平方計算
使用範圍:整數計算開根及平方,計算慢,gate count少
參考資料:MATH toolkit for Real-Time Programming by Jack W. Crenshaw CMP Books
原理說明:
這是我們常用的公式(n+1)^2=n^2+2*n+1
改寫為(n+1)^2=n^2+n+(n+1),其中n^2在上次計算可得到,所以只剩n及(n+1)且只使用加法就可以進行。
設計演算法為
a=Count
b=Last Sum= Sum
c=Sum=Last Sum+Count
d=Squart=Sum+Last Sum
排表為
a b  c d
 0  0   0  0
 1  0   1  1
 2  1   3  4
 3  3   6  9
 4  6   10 16
 5 10   15 25
若要取得平方,就將輸入做為計算的次數。計算停下來時,取出d就是答案。
要做開方,就將輸入和輸出比較,超過時停下來,取出a就是答案。
若要使用到小數,則使用定點數方式可以得到。


2009年3月3日 星期二

打造GTK的Forth程式語言介面

Forth連上GTK了,也就是連上其他函式庫也可以參照這個方法。
http://tutor.ksana.tw/ksanagtk/

我發現和Lua的Alien函式庫做法差不多。可見得這個作法是正確的。

C++光芒不再?

想使用能在一般平台上使用的語言,所以想學C++語言。

但因為也學了一些其他語言,所以有注意到C++語言的排名。

不幸的是C++的排名在下降,我覺得是否仍要學C++。並引發我認為是否C++的光芒已不再的這個議題。

找了一些資料了解到底C++為何排名下降。找到以下原因:

1.欠推廣
  編譯器開發廠商已不在推廣C++,這也和Free compiler的興起有關,使得C++不再有商機,也使推廣冷卻。

2.新人已被Java引走
  C/C++語言最強的資料型態:指標。這對於入門的人是危險的,也造成學習困難度。

  而且在一般電腦應用上,也不需要使用指標。所以入門者會選擇和C++類似的語言。
  又JAVA有跨平台能力,且有推廣,所以入門者紛紛轉向JAVA。

3.其他動態語言興起
  動態語言因為可以快速編寫,會比編譯語言好上手,所以新的語言多以動態語言為主。而商用語言就以快速編寫為導向有其商機,所以發展上比較快。
 
在實際上程式設計師的討論版中,C++仍為主力。表示一但上手,就不會放棄使用。

我認為主要是在語言支援上有其優勢,也就是C++有許多函式庫及延伸工具。使得在程式工程上仍有很大的優勢。

就以我的應用上來收集資料評估,要用C++語言在PC上做一個game,那就支援程式上的收集。發現真的以C++的支援函式庫多。

因為選擇多,所以可以找到合適使用的函式庫。使用其他語言則因函式庫不豐富,反而不好使用。

所以要真的做出有工程品質及效能的程式仍以C++語言建造會比較快。

結論就是C++語言上手是不容易,一但熟悉可以利用其函式庫快速建造。


2009年2月24日 星期二

為何使用Erlang

使用Erlang的原因是想找一個平行運算語言來學。於是在TIOBE上找找看,於是找到Erlang。

剛好也出了中文書,正好可以學起來。於是進行自學。

但這個語言也啟發我一些想法。原來平行語言要解決的果然比我想的要複雜的多,要是沒有參與不會想這個問題。

在使用Erlang有幾個特性和一般電腦語言不同的,像變數無法改變、數學表達的程式。

另外有一個全新的功能在其他語言未見到,就是程式熱抽換。也就是程式仍在執行時進行更新。這對on-line game是很需要的,也是這個語言現在會紅的原因。

使用Erlang和我的工作無相關,但我想要寫一些網路應用的小程式,那就使用新語言試試看。

這是我想使用這個語言來學習及應用的原因。有所進展再貼。


2009年2月18日 星期三

為何使用Forth

會使用Forth是一場機緣。但並不是完全沒有理由,在學的時候也有查過其特性才學的。
當時找到的資料是Forth是最小的作業系統混合語言。當時自認為對電腦很熟,想說已給了組合語言原始碼。大約千行的程式碼,應是不難破解其運作。
要了解作業系統及電腦語言的產生,Forth可以一次學會,這比一般分開學作業系統及電腦語言會快些。
結果是除了捷徑這件事是對的,其餘都是錯估。

初看Forth語言,很像是組合語言。因為有很多特性和C語言差很多,感覺要原始得多。
不過原始碼實在很難懂它是如何運作,最大的原因是,Forth系統的運作方式也是用Forth定義的。即使是用組合語言寫的,但高階部分是使用Forth語法。
故在自學Forth上是覺得入門門檻是高了些,因為還要去習慣Forth的習慣。
後來是和使用Forth的人在一起討論才對這個語言開始熟悉。在有人指點的狀況下,才能抓到Forth的重心。

在使用Forth上,最令我驚訝的是8051 Forth。因為在8051上是可以使用組合語言及C語言,但沒有一個語言可以做到動態編解譯程式,Forth就可以。
就以目前的功力來說,要在8051上做到動態編解譯程式,還真的找不到更精簡的架構。
動態解譯這項能力對Forth程式開發有很獨特的吸引力,它可以單獨執行函式,對機器做單一功能測試。這對於將電腦應用於機器測試上是很好的除錯能力。
大部分狀況用8051做控制是不大可能要做動態解譯來測試機器,但我在其他16位元及32位元上也不常見。

所以在Forth的功能表現上,有語言編譯的能力及作業系統管理特性。所以想說學了應可以學會編譯語言的方法及作業系統的知識。
剛好以Forth語言做為開發平台的公司有免費的討論會。所以有機會我便去參加討論會。
中間有許多人參與這個討論會,但我參加了二年才開始了解Forth的核心。可見得一開始真的是估錯了。
之所以會花二年的時間,一則是我並沒有急著用,另一個是一個月才一次討論,其中包括軟硬體設計。

Forth系統其程式碼很少,因為其函式很容易長得深,也造成其不易閱讀的特性。
但是確實有實現語言及作業系統機制,也因程式碼少,可以看見最簡單的作業系統及語言編譯方法,這對我了解電腦應用及原理有很大的幫助。
所以有段時間想用,但一直不易去使用。原因是可用的模組少。
以Win32Forth為例,是目前Windows平台上使用的Forth。但程式碼在Windows的函式太多(Windows內部函式也很多),一直不好上手。

最後目前我只能放在Dll的實驗上,看何時有比較好的機會再使用。


2009年2月13日 星期五

為何使用Lua

Lua原先是在尋找小語言時發現的。它是使用C語言寫成的,所以可以用於小型的系統上。原先希望可以用在微控器上。所以才學來玩。
因為自己對電腦語言的產生有興趣,所以也想看看電腦語言是如何做的。
後來發覺這個語言不錯,有一些C語言沒有的特色。像是多回傳值、無指標資料結構。
另外有函式語言的特性及簡單物件的表示法。
在實際使用上,用順了之後,發現這個語言雖小,但很好使用。
不用考量資料要多少欄位,就想到時再加上去,所以使用Lua開發時資料結構都不用擔心。
且具交談式開發的功能,可以不用寫程式直接試函式功能。

Lua真正出名是於"魔獸世界"中採用做為UI語言。不幸的是我完全沒有玩"魔獸世界"。它如何做為嵌入語言,我是沒有那麼清楚。
但是對於Lua如何改善應用程式,使之對於使用者界面,有很好的適應性。這方面我是很有期望。
所以個人認為Lua的使用比BASIC簡單,可以很容易讓一般User使用。這在推廣上有一定的吸引力。

以下為個人整理的特色:
說明文件
    有手冊,但沒有太多入門書
    
學習及除錯
    學習快
    除錯器功能不如商用語言方便
    
使用記憶體大小
    執行檔小
    
函式庫
    移植自C的函式庫很多
    
和其他語言連接能力
    和C有很好的連接性
    
資料操作
    很好
    
其他特性
    物件表示
    函式語言


2009年2月10日 星期二

櫻花開了

取泉水的路上看到的,春天已經到了。

RamDisk妙用

最近買了電腦,因記憶體便宜,所以使用4G RAM以上的容量。

在windows 32下自然是不能用到完,只能使用3G,且使用的顯示卡記憶體越大,可以用的就越少。

所以只能加裝ramdisk將用不到的記憶體取出,然後將pagefile及IE暫存檔等設進去。反正每次開機就是新碟,不用去整理。

後來還發現在ramdisk解壓縮速度很快,就算是1G RAM的機器我也會開一個64MB的ramdisk。這樣對硬碟的的碎裂程度會有很好的延緩。


可是最近又多發現一個用法,就是抓電腦病毒。

因為我沒有安裝防毒軟體,為了效能及省錢,只使用免費線上掃毒。

其實windows只要關閉適當開關,並不會很容易中毒。

目前我最常遇到的是USB病毒,皆是用ramdisk發現。

被感染時,ramdisk的隱藏檔會自動啟動,而且無法打開看隱藏檔功能,然後用Free commander去看,就多了一些檔案。

奇怪,開機是新碟,何時會有那些怪檔?不是使用者做的,就是病毒了。

奸詐的是免費線上掃毒是不解USB病毒的,這些USB病毒專偷線上遊戲帳號。好在我沒玩,但有玩也沒關係,人多不一定會找到你。

倒是有朋友用現金買虛擬幣,加上中USB病毒,很快的整個帳號內的人物就被剝乾。線上遊戲還真可怕。

那中毒如何解?就將怪檔案的檔名用google找,一般會找到免費解毒的程式,網路上的好心人仍不少。

因為中了幾次,找了一些手工解毒的文章,所以現在已練會手工解病毒了。


2009年1月18日 星期日

CPU部分功能新解

最近和人在網路上討論CPU設計。我寫出了對於堆疊(stack)及中斷(interrupt)的認知。


2004年在學了CPU設計同時,我也一併學到編譯器設計及作業系統原理。這段時間不是很長,大約一年,且一個月才有一天機會。

不過從退休教授那所學的,卻和一般書本完全不同。我學的Forth語言,本身就包含有語言及作業系統的組合。這和一般書分開的不同。

所以我必須一邊了解Forth系統,一邊比對。和現在書上的分類及技術上的不同。

不過也許是同時學,才發現CPU設計上一些功能上設計原理。


1.對於Stack的加入

  因Compiler原理看不懂,改看Yacc的應用,發現所有的Compiler是可以從Yacc中做出來。而Yacc其技術便是使用Stack。

  後來又看了Automata Theory,討論了簡單電腦語言。其中對於自動機(Automata)能做到的事給予描述。

  一個計算器(Computer)能因運作元件可以做到多少事加以證明。從一開始的字詞辦識,僅需使用記憶單元及運算單元。

  但對於Context Free Language來說,必須引入Stack元件。而所謂CFL(Context Free Language)是C語言之類的電腦語言工作之範圍。

  其實書本看到這裏我就有點看不是很懂,但可以知道,所謂電腦語言語法,有其工作能力及可以計算問題的範圍。

  當時我正好學會Verilog,心想其實如果FPGA的容量夠大,可能不需使用CPU這樣的結構就可以工作,那為何要將電腦語言濃縮成CPU。

  其實答案很明顯,節省硬體。也就是我們給定計算程序用來解問題,除了計算程序,結果必須有硬體,硬體要克服實現計算,將必須使用的功能濃縮,就是CPU。

  也就是計算器本身不一定由電子電路實現,也有可能由機械、水力、光能來實現計算及記憶。但加入Stack功能便可以寫入高階電腦語言(如C)來執行。

  由於Stack的能力,使得我對於電腦語言及CPU的演算能力有新的認知。原來電腦語言與電腦本身都是實行運算能力的一部分,而非分開發展的。
 

  a.對於無Stack CPU程式的撰寫

    這算是一個自我練習的題目,但很快的我找到了現實的CPU,那就是PIC微控器。
    沒有Stack那就表示,沒有subroutine可以用。結果程式不就只能寫成長長一條。

    可是還是有人可以在上面寫出程式功能塊,可以重覆使用,並引入參數。其運用技術是使用巨集(MACRO),這是組合語言常用招式。

    巨集實為文章抄寫取代,每次寫出,就會有對應的程式取代,取代完後,程式果真就是長長一條,是符合無Stack CPU來執行。但寫法又可以像一般函式呼叫,只是程式因巨集展開會增大很快。
    
  b.subroutine return stack和data stack的發現 

    主因在於我想解析C語言如何轉成組合語言,發現在X86及68K兩種CPU上不太一樣。X86使用一個Stack,而68K使用二個。

    68k將區域變數另外用一個Stack來存放。這個問題好玩的地方在,萬一程式寫不好,區域變數存取錯誤時,68K的程式仍不會馬上當,X86卻會。

    這使我意識到不同功能Stack最好分開管理,這也是後來RISC CPU要使用多個Stack,方便管理及增加效能。

    而我在看JAVA的虛擬機時,看到採用單一Stack設計,我就會知道一定會像X86一樣效能低且不穩定性高。
 
  我又研究了Lua語言,發現也有使用stack結構來完成虛擬機。一個stack運算機器無疑是完成電腦語言的基本骨架。


2.對於interrupt的加入
  本想,就算沒有這個功能,CPU一樣可以跑。有了也只是對於I/O反應快。
  但在學了作業系統後可不同了。

  有了interrupt,CPU可以在多個程式中轉移,這是多工所需要的。反之沒了interrput,現在作業系統將完全無法移上去。

  現代作業系統的主要功能是產生多工,及電腦資源管理。只要系統大,資源管理是必然。

  但多工的意義呢?我自己寫了一個在8051上的簡單多工系統,發表在8051的版上。
  這個版本的多工因不使用中斷,會使程式寫法大受限制。

  原來多工能力會影響寫程式的樣子,其實程式的寫法不應受CPU的執行力影響。其解法就是CPU必須加入多工,也就是加入interrupt。
 
  a.沒有interrupt時程式的寫法

    這也是自我練習題。結果沒想到竟學到Coroutine技術。其實這是非強制多工作業系統的技術,一個被遺忘的作業系統。

    也就是像一般程式寫法,結構要相同,但不使用interrupt的多工。其主要功能是開發一個coroutine函式,利用它進入及跳出程式。

    因為同一個函式同時可以產生進入及跳出,故名為Coroutine。
    Coroutine的發現,使我完完全全了解了從單晶片電腦到現代PC其上作業系統的演進程序。因為它交代了為何作業系統和單工系統中間的複雜度落差。

    單工系統只需管理共用變數,而作業系統的管理函式一下子暴增。原來是中間有一個被遺忘的作業系統,其管理函式數目介於兩者間。

    Coroutine技術也讓我了解如果純用軟體模擬多工的方法。
   

  b.interrupt和process的相關

    這是多工的反面看。從使用者角度來看。
    由於中斷加入,程式不再受CPU能力而要改寫原始碼。也就是單核心及多核心寫法是沒有差的(有共用變數時則有差)。

    另外一種說法是,使用者可以同時開幾個彼此無相關的程式一同運作,好像每個程式都有獨立CPU。
    這樣的用法不就是平常我們在用的Windows程式,我們一定同時開Word、Excel等程式。Windows要是沒有多工,那不就糟了。

    所以process就是一個利用interrupt產生之CPU的影像。

    也因有了process的觀念,作業系統可以簡單管理多核心CPU。這一切都源於interrupt的發明。


2009年1月5日 星期一

水星領航員

因為看到它的評分很高,不然完全沒有印象它是什麼。封面感覺有點像少女漫畫,所以本來我是不可能主動去看的。

我是先看到動畫版本。有許多人都會快轉片頭,沒想到它沒有固定片頭,我是都有在看片頭及片尾,所以還好。
看了第一集的感覺是劇情好慢,但竟不知不覺看了二集,就是一片DVD。後面還有幕後特集,依一般習慣當然是跳過。
看完了覺得劇情還不錯,就很平順好像也沒有什麼很特別的。因為劇情很慢,所以第二片就順著它的步調慢慢看。
其實這才是這部"水星領航員"真正要觀眾體會的。

沒想到慢慢看後,開始覺得其實看的感覺很舒服,就是一種放鬆,就像是在放假觀光的心情去融入劇情中。
又沒想到的時間就這樣過了,又看完一片,既然步調放慢了,就連幕後特集一併看吧!
看了發覺監制很用心,原來場景是如此考究。
看了二片之後,才開始會了解"水星領航員"為何是歸納為"療傷系"動畫。看了心情真的會好不少。
等我看到第一部最後時,已經又從原先的單純放鬆心情看,到開始受到劇情影響想要看下去。
所以就直接敗了整部"水星領航員第二部"及全套漫畫。

其實漫畫看了是不如動畫版本如此有感覺。這點在看第二部動畫時才了解原因,因為動畫版本在音樂上是很下功夫的。
所以整個劇情的感覺是被音樂整個拉展開來。有許多場景、感覺都是用音樂做了很好的提昇。

而看漫畫時,我也可能受到動畫版本的影響,看得相當投入。
其實漫畫劇情也是不錯,只是因風格及情緒若是沒有投入,只是感覺到很輕鬆的漫畫。

在動畫版本則是不同,會特別強化情感劇情,加上背景音樂帶出的情境,真的很令人感動。
不論是漫畫版或動畫版本,都已經結束了。劇情並不是很長,其實我覺得像這樣的小品,長度不長反而才會讓人有意猶未盡的感覺。

雖然我未看完動畫版本,但也引發我去思考為何這樣的小品作品會引發現代人在情感上的共鳴。
主角所經歷的也是一般人的經歷,學習、成長、成熟及別離。就男生來說,並不會有很強的感覺。
可是在出社會後,一直在拼工作,再加上遇到不好的同事、上司及老闆。漸漸的都會人的感情都變質了。不是很緊張,就是易怒,整天處在戰鬥狀態中。人之間的感覺也都被不好的情緒所環繞著。
對於出了社會一段時間人來說,情感差不多都冷凍了。所以要放鬆心情及情緒是不容易的。
"水星領航員"的世界則是提供都會人情感可以放下的環境,使用音樂放鬆並引入劇情中,讓人去感受樸質的鄉村人文,體會主角純真的情感。
這對都會人來說真的是一劑療傷良方。也難怪會稱為"療傷系"動漫畫,能溫暖了都會人冰凍已久的內心。
在看"水星領航員"時對於主角經歷所激發的情感,在放鬆的心情下,更能因為我們也曾經歷的感覺而產生情感上的共鳴。

另外在製作上,雖然只有電視劇製作成本,不過監制很用心的取材,找個性相似的配音員及音樂聲樂家。
良好的題材使得工作人員用心去製作,配音員也會投入感情。在參與人員的熱心下使得"水星領航員"呈現更為自然的感覺。
算是少數動畫做得比漫畫更有感覺的作品,甚至為了幕後工作的音樂人員,還特別做了一集非漫畫劇情將音樂人員一併畫入。
在製作上的用心,也在小地方影響著觀眾,也是動畫成功的因素之一。

"水星領航員"動畫雖分三部,但劇情很鬆散,就算單獨一集看,也並不會有連貫性問題,所以重看也沒有什麼壓力。反而看過的人,有時還會更想重看,放鬆兼重溫。

說了這麼多,但我是刻意避過劇情的,或是說看的感覺比劇情來得重要。
所以要放鬆心情去看這部好作品。

就個人來說,看了曾有幾天週遭人都看得出我心情超好,不過工作也沒做很好也是。哈哈...

取山泉水

住家後山上可以裝山泉水。因山路很陡,所以是騎機車上去的。剛好我的機車可以放一個30公升的水箱,於是都會用它來裝泉水。
可以取用的地方有幾處,會用管子打入山壁,泉水會從管子中流出來。第一次去會覺得很神奇,而且山頭就在抬頭不遠的地方,大約20~30米高而已。
照片上取水的地方不算是好的,最好的地方是一處石壁,整片石壁只有管子有水出來,對面有涼亭,所以有人從一早四點就去排了。
因為人太多,所以我只好找比較差的地方裝水。
之前家中泡茶是用逆滲透水,茶水是一般金黃色。可是用山泉水泡,一開始是金黃色,後來顏色會變深。而且山泉水的口感也比較滑順。
我裝了一次回家後,就不習慣使用逆滲透水來泡茶了。
不過也因水質好,久未下雨時水量變少時就很難裝到水了。