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的發明。


6 則留言:

  1. <恕刪>
    a.對於無Stack CPU程式的撰寫

        這算是一個自我練習的題目,但很快的我找到了現實的CPU,那就是PIC微控器。

    <恕刪>

    請參考--
    http://en.wikipedia.org/wiki/PIC_microcontroller#Stacks

    Stacks PICs have a hardware call stack, which is used to save return addresses.


    stack 抽象的來說是一種資料結構, array也是. 在CPU而言只是一種stack這種存取模式(以push-pop來改變存取的記憶體位址). 支援subroutine的是暫存器--stack point(SP), 用來在return指令中執行載入PC值(PC = SP). 至於其他暫存器要不要保存, 那又是另一回事了.



    [版主回覆03/25/2009 18:26:46]我看過PIC13的微控器,它只有二層stack,除了保留給中斷用之外,主程式是不能用的。這造成我必須思考如何不用stack而能寫程式。因為不用stack寫程式又要像要副程式一般的思考的寫法,是在我遇到PIC微控器才有的想法。
    後期的PIC當然加入stack的層數到可以用的地步。

    也謝謝你點出語句上的問題。PIC微控器並不是真的沒有stack,而是少到無法用。

    回覆刪除
  2. 參考資料:
    http://pic16.com/bbs/viewFile.asp?Boardid=8&ID=36

    指令 CALL: 調用子程序 (subroutine)

    pic本身就有呼叫subroutine的指令了, 還是這個指令只能在中斷模式使用?



    [版主回覆03/25/2009 19:27:08]問題不在指令能否用,是stack太少。

    回覆刪除
  3. pic 是個與 8051闢美的 mcu, 如果沒有辦法使用 subroutine這個基本功能, 如何能與 8051競爭?

    [版主回覆03/25/2009 19:28:05]你可以看PIC10及PIC12,和8051的等級差了一截。

    回覆刪除
  4. 假設pic10不讓使用者使用call這個指令, 它本身沒有實現這個功能, 我會認為是為了要節省成本. 亦即它不鼓勵使用者寫subroutine, 適合極小型的程式使用.
    但你為了寫出類似subroutine而使用macro, 程式變得很長(需要更大的RAM), 我想你該考慮的是換個適合的mcu.

    BTW, yahoo真難回文

    [版主回覆03/26/2009 09:45:12]用Macro會使程式變大,需要的是ROM。
    對於常寫組合語言的人來說仍是有常用的程式塊,總不能每次案子都從頭寫。使用Macro將常用的程式塊打包可以做到程式重利用,這是必須的技巧。
    至於會使用到這種不完整功能的mcu,通常是價格因素,對工程師來說有好用的mcu為何不用,常然是有別的問題。不然這種mcu應是早該滅絕了。
    PIC系列我沒有用過,但因對CPU結構有興趣,才會看許多不同型式的cpu/mcu。也才會讓我有機會看到不同結構下的特性。

    回覆刪除
  5. 沒錯, 一個cpu/mcu能存在, 一定有它最合適的市場.

    回覆刪除
  6. stack 是最天才的發明之一
    電腦一堆東西都用到stack..

    想知道電腦怎麼運作的
    建議去讀computer system A programmer's perspective  (2nd edition)整篇看完
    作者目前還有在carnegie mellon 上課

    JAVA(JVM)本身的設計就是在多CPU的環境發揮最好的效能

    [版主回覆04/29/2010 11:10:29]Stack真正的威力,並不是我在學CPU及設計CPU時學到,反而是在學Compiler時才了解。

    因為自學Compiler時,完全看不懂,另外找更基礎的書時發現到Computer Theory,它才會真正說明Stack的用處。

    不過Computer Theory有時會有其他名字,我有二本書是講一樣的東西,但一本是Formal langurage theory,另一本是Automata theory。

    在早期CPU未商品化前,就已經有人開發出老鼠走迷宮的電子計算器,就已經在使用Stack。

    利用Stack計算的機器,在實現後,分成硬體及軟體二條路發展。在硬體方面則是發展成為CPU,在軟體方面則是發展為Compiler。

    也就是真正的Computer工作時,必須由Compiler及CPU共同完成。
    所以了解Compiler才能夠有效操作電腦語言,做使用者想做的事。
    了解CPU則是知道要如何寫程式才會讓硬體發揮最大效率。

    回覆刪除