2014年4月7日 星期一

巨集與函式的差異


設計程式時,有很多地方可使用含有引數的巨集或是使用函式,到底應選擇哪種方式撰寫,我們可由時間(Time)空間(Space)兩方面來考慮:

1. 由於巨集在編譯前先進行前處理時,會將巨集進行代換變成程式中的敘述。若巨集引數稍微使用不當易引起副作用。至於函式則不會發生此種現象。

2. 若在程式中使用到 多次巨集,在進行編譯前,前置處理器會進行取代的動作,因此較費時一點。但執行時不必像呼叫函式時,必須跳到函式所在處,待執行完再返回原呼叫處的下一個敘述,因此巨集執行時間較快,但程式空間加長。

3. 若在程式中呼叫函式多次,卻只要在程式中留下一份函式的拷貝,呼叫函式時跳到函式所在處,待執行完再返回原呼叫處的下一個敘述,因此函式比巨集較花費時間,也就是說函式執行時間較慢,但程式長度不會長。 

4. 函式在編譯時會做參數檢查;巨集指引編譯前己變成敘述,所以不會做參數檢查。

編譯前經過前置處理器會將程式中的巨集直接轉換成所指定的敘述。和函式比較起來,使用巨集可以省掉程式執行時再去呼叫函式的時間,以縮短程式的執行時間,增加程式的可讀性及效率。因此定義巨集可以替代一些簡單的運算式或單行的簡單函式,而函式則適用於較複雜的功能

巨集 (macro)
優點:執行速度快,沒有堆疊的 push pop 動作的需要,減少時間的耗損。

缺點:巨集被呼叫多次以後,會耗損存放及使用大量的記憶體空間。
函數 (call function/call subroutine)
優點:即使函數被呼叫多次,在記憶體中仍只有一份實體,較節省記憶體空間。能節省存放及使用的記憶體空間。

缺點:執行速度較慢,需花費時間在堆疊的 push pop 動作上。




參考資料 :C & C++ 程式設計經典

2014年4月6日 星期日

Search Algorithms

1.循序搜尋法(sequential searching)
   又稱線性搜尋法(linear search),為一筆一筆資料依序比對,直到找到所要搜尋的記錄為止。
   時間複雜度為O(n)
   平均搜尋長度= ( 1 + 2 +3 + ...... + n ) / n = ( n + 1 ) / 2

Example
int seqsearch(int a[], const int key, const int n){
    int i;
    for(i = 0 ; i < n ; i++)
        if(a[i] == key) return i;
    return -1;
}

2.二元搜尋法(binary searching)
   取中間值與搜尋值比對
   時間複雜度為O(log2n)
  差的情況下, n / 2 ^ m = 1 ,m = log2n,n個串列,m次比對。
   須事先予以排序
   中間值:mid = ( low + high ) / 2

Example 
//a[] is an sorted integer array
int binarysearch(int a [], const int x, const int n){
    int left = 0, right = n - 1;
    while (left <= right){
        int middle = (left + right) / 2;
        if(x > a[middle]) left = middle + 1;
        else if(x < a[middle]) right = middle - 1;
        else return middle;
     }
     return -1;
}


2014年4月5日 星期六

管線(Pipeline)

      管線,是現代計算機處理器中必不可少的部分,是指計算機指令處理過程拆分為多個步驟,將多個指令的執行動作重疊,以達到加速程式執行之目的,並通過多個硬體處理單元並行執行來加快指令執行速度。

Multithreading v.s. Multitasking v.s. Timesharing

程式具有多工(Multitasking) 多重處理(Multiprocessing)的能力 


什麼是執行緒 ?

n  支援多重處理的執行控制機制,它可以執行程式中任何一組相關且可與程式中其它部分多重並行處理程式片斷

2014年4月4日 星期五

Division


Division       Divisor:除數   Dividend:被除數

Issues
l  Divide by zero

l  Need to deal with signed values





Multiplication



第一版乘法運算及硬體
  • 乘積暫存器先預設為0
  • 如果每個步驟須花費一個時脈週期,這一版的乘法運算就要花費100個時脈週期才能完成。
流程圖













硬體結構














2014年4月3日 星期四

CISC v.s. RISC

Introduction 

   處理器的指令集可分為CISC(Complex Instruction Set Computer)RISC(Reduced Instruction Set Computer),在現代的處理器指令集設計中,兩者均有廣泛的應用,本文主要是兩種指令集特性及其應用的比較。  


Data race condition


      A race condition is an undesirable situation that occurs when a device or system attempts to perform two or more operations at the same time, but because of the nature of the device or system, the operations must be done in the proper sequence in order to be done correctly.

Synchronization and Asynchronization


        所謂的「同步(Synchronous)」,和「非同步(Asynchronous)」,是我們在撰寫程式或是開發系統時,常會聽到的形容詞。這兩種概念可以用在許多地方,包括描述程式設計的模式,所以,我們會看到所謂「同步程式設計(Synchronous Programming)」,以及「非同步程式設計(Asynchronous Programming)」。這兩個名詞分別描述了兩種不同的程式設計模式,但它們之間有什麼差別呢?

Build background with cvRunningAvg

  1. #include <cv.h>
  2. #include <highgui.h>
  3.  
  4. int main()
  5. {
  6.      IplImage *pFrame = NULL;
  7.      IplImage *pGrayImg = NULL;
  8.      IplImage *pFGImg = NULL;
  9.      IplImage *pBGImg_8U = NULL;
  10.      IplImage *pBGImg_32F = NULL;
  11.      IplConvKernel * pKernel = NULL;
  12.      CvCapture *pCapture = cvCreateCameraCapture(1);
  13.  
  14.      cvNamedWindow("webcam", 1);
  15.      cvNamedWindow("background", 1);
  16.      cvNamedWindow("foreground", 1);
  17.  
  18.       pKernel = cvCreateStructuringElementEx( 5, 3, 0,0
  19.         , CV_SHAPE_ELLIPSE, NULL);
  20.  
  21.      if(!(pFrame = cvQueryFrame(pCapture)))
  22.      {
  23.          fprintf(stderr, "Can not open");
  24.          return -1;
  25.      }
  26.      else
  27.      {
  28.          pGrayImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  29.          pFGImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  30.          pBGImg_8U = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  31.          pBGImg_32F = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_32F, 1);
  32.    
  33.          cvCvtColor(pFrame, pGrayImg, CV_BGR2GRAY);
  34.  

Background Subtraction Using Mask

  1. #include <highgui.h>
  2. #include <cv.h>
  3. int main()
  4. {
  5.         IplImage* pFrame=0;
  6.         IplImage* pGrayImg=0;
  7.         IplImage* pFGImg=0;
  8.         IplImage* pBGImg=0;
  9.         IplImage* pBGImg_Gray=0;
  10.         IplImage* temp=0;
  11.         CvCapture* cap = cvCreateCameraCapture(1);
  12.  
  13.         if(!(pFrame = cvQueryFrame(cap))) return -1;
  14.         else
  15.         {
  16.                 pFGImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 3);
  17.                 pGrayImg = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  18.                 temp = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  19.                 pBGImg_Gray = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
  20.                 pBGImg = cvCloneImage(pFrame);
  21.         }
  22.  
  23.         while(1){
  24.                 pFrame=cvQueryFrame(cap);
  25.                 cvShowImage("present",pFrame);
  26.                 cvShowImage("background",pBGImg);
  27.  
  28.                 cvCvtColor(pFrame, pGrayImg, CV_BGR2GRAY);
  29.                 cvCvtColor(pBGImg, pBGImg_Gray, CV_BGR2GRAY);
  30.                 cvAbsDiff(pGrayImg, pBGImg_Gray, temp);
  31.                 cvThreshold(temp, temp, 40, 255, CV_THRESH_BINARY);
  32.  
  33.                 cvZero(pFGImg);
  34.                 cvCopy(pFrame, pFGImg, temp);
  35.                 cvShowImage("foreground", pFGImg);
  36.        
  37.                 int key=cvWaitKey(1);
  38.                 if(key==27)break;
  39.                 if(key=='b') cvCopyImage(pFrame, pBGImg);
  40.  
  41.         }
  42.         cvReleaseCapture(&cap);
  43. }