fflush( )

一般電腦在執行IO的時候都會先將資料存在buffer裡面

等到system有空的時候才會讓資料寫入硬碟裡。因此我們要確保資料已經寫入

這時候就可以用fflush這個function。

以下是在論壇找到別人回覆的資料:

flush(stdin)刷新標準輸入緩衝區,把輸入緩衝區裡的東西丟棄  
fflush(stdout)刷新標準輸出緩衝區,把輸出緩衝區裡的東西打印到標準輸出設備上。

 

Example:

取自:http://www.cplusplus.com/reference/clibrary/cstdio/fflush/

/* fflush example */
#include 
char mybuffer[80];
int main()
{
   FILE * pFile;
   pFile = fopen ("example.txt","r+");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fputs ("test",pFile);
     fflush (pFile);    // flushing or repositioning required
     fgets (mybuffer,80,pFile);
     puts (mybuffer);
     fclose (pFile);
     return 0;
  }
}
 
在linux上可以下sync這個指令。讓他將"記憶體"的內容寫入"硬碟"。
並不是IO的buffer..........。

 

0.0f ????????

0.0跟0.0f有什麼不一樣?
在C語言上印出來的結果都是一樣的?差在那邊?

0.00 is a double (64 bits)
0.0f is a float (32 bits)

嗯…就這麼簡單

把i386.deb的套件安裝在amd64的PC上

本文取自:沙中's Blog

方法1:以Scratch1.4為例
  1. 下載scratch_1.4.0.debian.12_i386.deb 並複製到[家目錄]底下
  2. http://frozenfox.freehostia.com/cappy/ 下載getlibs-all.deb 後,快按2次安裝
  3. 將下載的檔案copy到家目錄下
  4. 貼上 sudo dpkg -i --force-all scratch_1.4.0.debian.12_i386.deb                
     即可進行安裝直到完成! ★★其他套件的i386.deb也可以用同樣的方法,在步驟4.改為套件名稱即可吧!

方法2:以安裝realplayer 11為例
  1. 先安裝i386 lib
    sudo apt-get install ia32-libs* 或套件庫裡輸入  "ia32-libs"
  2. 安裝deb
    sudo dpkg --force-architecture -i 套件名
  3. ex: 安裝realplayer 11將檔案放到[家目錄]資料夾下
    sudo dpkg --force-architecture -i RealPlayer11GOLD.deb
★★移除強制安裝的i386deb(在套件庫找不到)
  1. sudo dpkg -P 套件名
  2. ex: 移除強制安裝的realplayer11
    sudo dpkg -P realplay
來自amd64系統上安裝及移除i386deb指令


測試心得:無法成功在debian執行…

debian dpkg 常用指令

常用 Dpkg 指令表:
命令 作用
dpkg -i package.deb
安裝包
dpkg -r package
刪除包
dpkg -P package
刪除包(包括配置文件)
dpkg -L package
列出與該包關聯的文件
dpkg -l package
顯示該包的版本
dpkg –unpack package.deb
解開 deb 包的內容
dpkg -S keyword
搜索所屬的包內容
dpkg -l
列出當前已安裝的包
dpkg -c package.deb
列出 deb 包的內容
dpkg –configure package
配置包
注意:更多選項可通過 dpkg -h 查詢,有些指令需要超級用戶權限才能執行。


在 Debian 使用 alien 處理 RPM 套件:
alien 可處理 .deb、.rpm、.slp、.tgz 等檔案格式, 進行轉檔或安裝.
於 Debian 安裝非 Debian 套件時, 可使用 alien 進行安裝.
安裝 alien 套件: apt-get install alien
  • 在 Debian 安裝 RPM 套件: alien -i quota-3.12-7.i386.rpm
  • 製作成 deb 的套件格式: alien -d quota-3.12-7.i386.rpm
  • 製作成 rpm 的套件格式: alien -r quota_3.12-6_i386.deb




備註:rpm vs dpkg

安裝
目的 rpm 用法 dpkg 用法
安裝指定套件 rpm -i pkgfile.rpm dpkg -i pkgfile.deb
查詢
目的 rpm 用法 dpkg 用法
顯示所有已安裝的套件名稱 rpm -qa dpkg -l (小寫 L)
顯示套件包含的所有檔案 rpm -ql pkgname (小寫 L) dpkg -L pkgname
顯示特定檔案所屬套件名稱 rpm -qf /path/to/file dpkg -S /path/to/file
查詢套件檔案資訊 rpm -qip pkgfile.rpm (顯示套件資訊)
rpm -qlp pkgfile.rpm (小寫 L, 顯示套件內所有檔案)
dpkg -I pkgfile.deb (大寫 I )
dpkg -c pkgfile.deb
顯示指定套件是否安裝 rpm -q pkgname (只顯示套件名稱)
rpm -qi pkgname (顯示套件資訊)
dpkg -l pkgname (小寫 L, 只列出簡潔資訊)
dpkg -s pkgname (顯示詳細資訊)
dpkg -p pkgname (顯示詳細資訊)
移除
目的 rpm 用法 dpkg 用法
移除指定套件 rpm -e pkgname dpkg -r pkgname (會留下套件設定檔)
dpkg -P pkgname (完全移除)

debian要打BBS怎麼辦

有好用的軟體喔~

apt-get install pcmanx-gtk2
  
參考網頁:http://code.google.com/p/pcmanx-gtk2/

關於#include引用方式

在 CUDA_NVIDIA_GPU_Computing_SDK 中,有部分API可以使用可以偵錯很方便
都在cutil.h 中,但是在nvcc的library path 與 include path中是沒有預設的。
(我猜是因為SDK可以用可以不用裝,而且每個人裝的路徑不同)
因此可以從nvcc_2.0.pdf中查到一些option,可以用,下例中紅色的部分。
詳細內容可以在~/NVIDIA_GPU_Computing_SDK/C/common/inc中找到
//include project file
#include

int main(){
    int msize = 100;
    //allocate memory
    float *h_a;
    h_a = (float*)malloc(msize*sizeof(float));
    float *d_a;
    cudaMalloc((void**)&d_a,msize*sizeof(float));   
    //test API....
          CUDA_SAFE_CALL(cudaMemcpy(d_a,h_a,msize*sizeof(float),cudaMemcpyHostToDevice));   
 
    //free memory
    free(h_a);
    cudaFree(d_a);           
    return 0;
}


因為沒有library與headfile所以如下:
nvcc -g -I/home/zcli/NVIDIA_GPU_Computing_SDK/C/common/inc -L/home/zcli/NVIDIA_GPU_Computing_SDK/C/common/lib/linux cudaapi.cu

CUDA "unspecified launch failure"

本文章取自:http://www.herikstad.net/2009/05/cuda-unspecified-launch-failure.html

The error "unspecified launch failure" usually means the same as "segment fault" for host code. Check that your code does not try to access any areas outside the arrays being used. A common mistake is using 'the whole idx' instead of just the thread id to access shared memory. Here's an example:

int idx = blockIdx.x * blockDim.x + threadIdx.x;
shared[idx] = input[idx];


will give you an error and should look like this:

int idx = blockIdx.x * blockDim.x + threadIdx.x;


int tid = threadIdx.x;
shared[tid] = input[idx];


注意:shared memory 的 index 只能用threadIdx。
      因為shared memory load data 是以一個 half-warp load。


My kernel...

__global__ void kernel(float *in,float *out){
 
  //declare share memory
  //extern is use kernel set memory size
  extern __shared__ float tempsa[];
 
  //set global index
  int globalIdx = blockIdx.x*blockDim.x+threadIdx.x;
 
  tempsa[threadIdx.x]= in[globalIdx];
  __syncthreads();
  out[globalIdx] = tempsa[threadIdx.x];
  __syncthreads();

  return ;
}

CUDA 程式設計(2) -- SIMT概觀

文章取自PTT videcard版 作者:a5000ml

※ 第二章 SIMT 概觀 ※

所謂 SIMT (single instruction multi threads) 指的是單一指令對應多執行緒的計算機架構,利用硬體的 thread 來隱藏 I/O 的延遲 (效果有點類似之前 Intel 的hyper-threading,不過那不是 single instruction),nVidia 進一步地讓這些執行緒可由程式控制,用群組的方式讓一堆執行緒執行相同的指令,並利用超多核心來強化它(例如 8800 GTX 有 128 顆、GTX280 有 240 顆)。

簡而言之,它是把超級電腦的平行架構,濃縮到單晶片中,所以產生這樣的效能(例如我實驗室裡的 kernel,在 GTX280上跑的效能是 Intel Q9300 的 30 多倍,這測量的時間是實際跑完的時間,用 CPU 的高精度 timer 測量出來的,對照的是用intel 自家的 compiler 進行 SSE3 最佳化過的)。

不過剛開始進入這多執行緒的模型,還真的有點不太習慣哩。

◆ CUDA 的平行化程式設計模型

名詞定義
        網格(Grid)    :包含數個區塊的執行單元
        區塊(Block)   :包含數個執行緒的執行單元
        執行緒(Thread):最小的處理單元 (實際寫程式的環境)

CUDA 的平行化模型是將核心交由一組網格執行,再將網格切成數個區塊,然後每個區塊
再分成數個執行緒,依次分發進行平行運算。

◆ 內建變數

我們可以透過內建變數來辨識每個執行緒
基本的內建變數如下,它們只可以使用在 kernel 的程式碼中:

        uint3 gridDim  :網格大小   (網格包含的區塊數目)
        uint3 blockIdx :區塊索引   (區塊的ID)
        uint3 blockDim :區塊大小   (每個區塊包含的執行緒數目)
        uint3 threadIdx:執行緒索引 (執行緒的ID)

其中 uint3 為 3D 的正整數型態

       struct uint3{
                unsigned int x;
                unsigned int y;
                unsigned int z;
       };
另外還有
       struct dim3{
                int x;
                int y;
                int z;
       };

可以運用它來實做更高層次的平行運算結構,不過現階段,先不要管這種複雜的結構,
把它當成單一正整數即可,也就是 y 和 z 都當成是 1,只用 uint3 的 x。

◆ 網格 & 區塊大小 (gridDim, blockDim)

CUDA 透過指定網格和區塊的大小形成平行化的程式陣列,總執行緒數目為網格大小和區塊大小的乘積,而 gridDim, blockDim 這兩個變數在 kernel 函式中為內建的唯讀變數,可直接讀取

        總執行緒數目 = 網格大小(gridDim) x 區塊大小(blockDim)

例如下圖為 (網格大小=3, 區塊大小=4) 所形成的核心,它具有 12 個獨立的執行緒
       +------------+-----------+-----------------------+
        |                |                | thread 0   (id  0) |
        |                |                +----------------------+
        |                |                | thread 1   (id  1) |
        |                |  block 0 +----------------------+
        |                |                | thread 2   (id  2) |
        |                |                +----------------------+
        |                |                | thread 3   (id  3) |
        |                +-----------+----------------------+
        |                |                | thread 0   (id  4) |
        |                |                +---------------------+
        |                |                | thread 1   (id  5) |
        |  grid       |  block 1  +---------------------+
        | (kernel)  |                | thread 2   (id  6) |
        |                |                +---------------------+
        |                |                | thread 3   (id  7) |
        |                +-----------+----------------------+
        |                |                | thread 0   (id  8) |
        |                |                +---------------------+
        |                |                | thread 1   (id  9) |
        |                |  block 2 +----------------------+
        |                |               | thread 2   (id 10) |
        |                |               +----------------------+
        |                |               | thread 3   (id 11) |
        +-----------+-----------+-----------------------+
        (圖二)
◆ 呼叫 kernel 的語法

在 CUDA 中呼叫 kernel 函式的語法和呼叫一般 C 函式並沒什麼太大的差異,
只是多了延伸的語法來指定網格和區塊大小而已:

        kernel_name <<>> (arg1, arg2, ...);
        ^^^^^^^^^^^     ^^^^^   ^^^^^^      ^^^^^^^^^^^^^^^
        核心函式名   網格大小   區塊大小    函式要傳的引數(和C相同)

        所以只是多了 <<>> 指定大小而已 ^^y

其中 gridDim 和 blockDim 可以是固定數字或動態變數,例如

    (1) 固定數字
        ooxx_kernel<<<123,32>>>(result, in1, in2);

    (2) 動態變數
        int grid  = some_function_g(); //計算網格大小
        int block = some_function_b(); //計算區塊大小
        ooxx_kernel<<>>(result, in1, in2);


◆ 區塊 & 執行緒索引 (blockIdx, threadIdx)

我們可以用區塊和執行緒索引來定出正在執行的程式位置,以決定該載入什麼樣的資料,而 blockIdx, threadIdx 這兩個變數和 gridDim, blockDim 一樣,在 kernel 中也是內建的唯讀變數,可直接讀取

例如在(圖二)中,我們要定出每一個小兵的唯一的 ID,可用下面這段程式碼

        int id = blockIdx.x*blockDim.x + threadIdx.x;

要產生(圖二)配置的 kernel 呼叫為

        kernel<<<3,4>>>(arguments);

其行為如下
(1) 傳入的網格和區塊大小為 1D 正整數,所以 uint3 中只有 x 有用到,其它 y=z=1
(2) 網格大小   gridDim.x   = 3       (每個網格包含 3 個區塊)
(3) 區塊大小   blockDim.x  = 4       (每個區塊包含 4 個執行緒)
(4) 區塊索引   blockIdx.x  = 0,1,2   (每個 thread 看到的不一樣)
(5) 執行緒索引 threadIdx.x = 0,1,2,3 (每個 thread 看到的不一樣)
(6) 區塊基底   blockIdx.x*blockDim.x = 0,4,8
(7) 區塊基底加上執行緒索引  id = blockIdx.x*blockDim.x + threadIdx.x
    = 0,1,2,3,  4,5,6,7,  8,9,10,11

所以我們便可得到一個全域的索引,即每一個小兵的唯一的 ID (圖二中的 id 欄)。

◆ kernel 函式的語法

用 CUDA 寫 kernel 函式寫一般 C 函式也是沒什麼太大的差異,只是多了延伸語法來
加入一些特殊功能,並且標明這個函式是 kernel 而已:

        __global__ void kernel_name(type1 arg1, type2 arg2, ...){
                ...函式內容...
        };

其中
(1) __global__  : 標明這是 kernel 的延伸語法
(2) void        : kernel 傳回值只能是 void (要傳東西出來請透過引數)
(3) kernel_name : 函式名稱
(4) type1 arg1, type2 arg2, ... : 函式引數 (和 C 完全相同)
(5) 函式內容    : 跟寫 C 或 C++ 一樣 (但不能夠呼叫主機函式)
(6) global 函式只能在 host 函式中呼叫,不能在其它 global 中呼叫。

◆ 小結
以上是 CUDA 平行化程式設計的概觀,和傳統 C/C++ 的差異便是它這種的 SIMT 結構,
也許你會覺得奇怪,為什麼要分成兩層的 grid/block 結構,直接一層就配多個 thread
不是更簡單,這牽涉到它硬體上的細節以及成本問題(後面章節會解釋),再者單層結構
不見得有效率,會增加同步化時執行緒等待的問題,使用兩層結構,可以使 block 單元
彈性的選擇同時或者循序執行,增加往後硬體發展和軟體重用的彈性。

CUDA 程式設計(1) -- 簡介

文章取自PTT videcard版 作者:a5000ml
※ 引言 ※

    從軟體設計角度來看,CUDA 寫作並不困難,困難之處在於如何最佳化,它需要了解不少硬體的細節。一般而言未最佳化的程式在 GPGPU 上面執行,可以比傳統的 CPU 快上 5~10 倍,而最佳化過的程式,往往還能再增速 5~10 倍,達到 25~100 倍的效能。

    CUDA 和傳統 C++ 最大的差異在於「平行化的程式設計」vs.「序列化的程式設計」,例如傳統上透過迴圈執行數千次的程式碼,在 CUDA 上就可以將它拆解成數百個同時執行的執行緒,每個執行緒只執行十幾次而己,因此產生數十到數百倍的效能。

    CUDA 是在傳統 C++ 的基礎上,加入一些延伸語法,以及輔助的函式庫,而形成的一種程式語言,一般而言只要熟悉 C 或 C++,就很容易上手 (可能比 Java 容易上手,因為傳統 C/C++ 的函式庫都可以用),編譯好的程式碼,也可以跟其它語言做不錯的聯結。

    在接下來幾篇文章中,我們從簡單的軟體設計角度開始,介紹 CUDA 如何寫作,逐漸
帶出硬體細節,然後介紹最佳化的一些技術。

※ 第一章CUDA程式如何執行 ※

◆ 名詞 ◆

主機 (host)  :插顯示卡那台PC。
裝置 (device):顯示卡。
核心 (kernel):在顯示卡上執行的程式碼區段。

◆ 執行流程 ◆

因為 GPGPU 屬於外部裝置(device),其機器指令有別於傳統 CPU,所以程式核心(kernel) 必須經過特殊編譯後,在執行時期和所需資料由主機(host)送到裝置中,並在執行完成後,將結果資料傳回主機,流程如下。

           主機(host)  PC                                                裝置(device)  顯示卡

                                傳送資料到顯示卡記憶體中
(1)     主機記憶體 ------------------------------------------>> 顯示卡記憶體


                               傳送程式碼(kernel)到顯示卡
(2)     主機記憶體 ----------------------------------------->> 顯示卡記憶體


(3)     主機做其它的事 or 閒置                                    執行顯示卡中的程式(kernel)

                                    傳回執行結果
(4)     主機記憶體 <<----------------------------------------  顯示卡記憶體

實際上,CUDA 提供了很多 API 簡化這些流程,包括記憶體在兩者間的搬移,顯示卡記憶\
體的配置與釋放,kernel 設定、啟動與同步等,所以上面的每一個步驟其實就是去叫用CUDA的函式而已。

◆ 編譯流程 ◆

簡易的編譯流程如下,只要先準備好副檔名為 .cu 的 CUDA 程式碼檔案,然後使用CUDA
的編譯器 (nvcc) 來編譯即可,進階的編譯流程以後再介紹。

                       nvcc
    .cu 檔案  ----------> 可執行檔 or 目的檔

其中 .cu 檔案可以同時包含在 host 中執行的傳統 C++ 程式碼,以及在 GPGPU 中執行的 kernel 程式碼。

##補充:nvcc可以把.cu的檔案編譯分成是兩個部分,一個是利用gcc來編譯C語言的部分
                另外cuda部分編成是PTX的組合寫言。

C語言- clock() 運用

Example1:開始計時與結束
#include
#include
double ms_time();
int main(void)
{
  float a[100000],b[100000],c[100000];
  int i,j;

  //宣告clock function
  clock_t start, end;
  //開始計時
  start = clock();
  //以下亂寫,單純讓電腦跑久一點
  for(j=0;j<1000;j++){
    for(i=0;i<100000;i++){
      a[i] = drand48()*5;
      b[i] = drand48()*5;
      c[i] = a[i]*b[i];
    }
  }
  //計時結束
  end = clock();
  printf("The time was: %f\n", (double)(end - start));

  return 0;
}
備註:這樣發現跑出來的時間是以小時為單位,如下改成是以毫秒為單位。

Example2:以毫秒為單位

#include
#include
double ms_time();
int main(void)
{
  float a[100000],b[100000],c[100000];
  int i,j;
  double start, end;
  start = ms_time();

  for(j=0;j<1000;j++){
    for(i=0;i<100000;i++){
      a[i] = drand48()*5;
      b[i] = drand48()*5;
      c[i] = a[i]*b[i];
    }
  }
  end = ms_time();
  printf("The time was: %f\n", (double)(end - start));

  return 0;
}
double ms_time(){
  return (double)clock()/CLOCKS_PER_SEC*1000;
}

備註:clock()/CLOCKS_PER_SEC 在這邊就是以為單位

安裝win32 codecs編碼器

文章取自:楊錦昌老師 - 圖解 Fedora Core 3 桌面調校


1.到「http://www.mplayerhq.hu/MPlayer/releases/codecs/」網站,
  下載「all-20050412.tar.bz2----有新版可以下載新版。

2.su -
  #變成 root 身份
  cd /home/帳號
  #進到下載的資料夾
  tar jxvf all-20050412.tar.bz2
  #解壓縮

3.mv all-20050412 /usr/local/lib/codecs
  #將解開的資料夾移到「/usr/local/lib」,且更名為「codecs」
  ln -s /usr/local/lib/codecs /usr/lib/win32
  #建立連結


Install Liu in Linux

*移除Scim(Debian/Linux預設安裝Scim)
#apt-get remove scim
*安裝Gcin (已經裝好可省略此步驟)
   1. #apt-get install gcin im-switch
      (安裝gcin和im-switch←可簡單地切換輸入法)
   2. #im-switch -s gcin
      (將gcin更改成預設輸入法)
   3.重新登入

*安裝 嘸蝦米 輸入法

   1. wget http://edt1023.sayya.org/misc/noseeing-6.tar.gz #下載嘸蝦米的 table
      (自已Xuite也有上傳....)
   2. mkdir tmp; cd tmp
   3. tar zxvf noseeing-6.tar.gz
   4. mv noseeing.gtab /usr/share/gcin/table/
   5. Gcin圖示按右鍵設定內定輸入法, 即可使用(也可以順便將不會用到輸入法刪除)

psftp常用指令

bye 結束 psftp 。
cd 改變遠端工作目錄。
chmod 改變遠端檔案的權限以及屬性。
del 刪除遠端檔案。
dir 列出遠端目錄內的所有檔案。
exit 結束 psftp 。
get 從遠端下載指定檔案。
help 列出本使用說明。
lcd 改變近端電腦的工作目錄
lpwd 顯示目前近端電腦的工作目錄
ls 列出遠端目錄內的所有檔案。
mkdir 在遠端建立一個新的指定目錄
mv 搬移遠端檔案或更改檔案名稱
open 連接指定遠端伺服器
put 從近端電腦上傳指定檔案至遠端
pwd 顯示遠端電腦的工作目錄
quit 結束 psftp 。
reget 延續下載未完的指定檔案
ren 搬移遠端檔案或更改檔案名稱。
reput 延續上傳未完的指定檔案。
rm 刪除遠端檔案。
rmdir 刪除遠端整個目錄。