Wednesday, February 01, 2012

[轉錄]C/C++ 的多維動態陣列



http://ehome.hifly.to/showthread.php?threadid=357


多維動態陣列在 C 中 大概只能用 malloc,但這在一維時尚
不構成問題,但需要多維陣列時怎麼辦呢?這算是程式論壇
最常被問到的問題之一了。
我把它整理了相關的回覆,都只用二維做說明,更多維的陣列
類推即可。
就從 C 談起吧!

動態產生一個[m][n]陣列 Array 的方法 
code:
int i; int **Array; Array= (int **)malloc(m*sizeof(void *)); for (i=0; i Array[i]=(int *)malloc(n*sizeof(int *));

這樣你就有一個 int Array[m][n]; 可以用了
是C 喔!不是 C++
但這不夠好,若你要的是一個較大的mXn陣列,那麼太多的malloc
會使記憶體碎片化(memory fragment)!沒關係,窮則變,變則通!
問題既出在for loop不斷的 memory allocation,就從那兒下手: 
code:
int i; int **Array, *pData; Array= (int **)malloc(m*sizeof(int *)); pData= (int *)malloc(m*n*sizeof(int)); for (i=0; i Array[i]=pData;

注意到嗎?這次只用了二次的malloc。
當要release memory也只要free Array[0] 和 Array 就成了!
(注意先free Array[0] 再 free Array)
如果嫌兩個alloc/free還是太多,也可簡單併成一個: 
code:
int i; int **Array, *pData; Array= (int **)malloc(m*sizeof(int *)+m*n*sizeof(int)); for (i=0,pData= (int *)(Array+m); i Array[i]=pData;

要 free 時只要 free Array 就行了,帥吧?
如果用的是C++,那可用的方法就更多了!

《幼幼班》嘗試錯誤的階段
?> int Array[][] = new int [10][20];//這樣行ㄇ?
當然不行! int Array[][]不是一個指標,而且只能有
一維為不定大小。

《小班》終於會從1數到100了
?> 那...
?> int *Array[] = new int [10][20];//這樣行ㄇ?
有點想法了!但可惜的是 '*' 在 C++的語法是修飾前面的
識別字,所以 int *Array[]的意思是 "Array是一個 int 指標
的一維陣列!"

如果能使那個 '*' 以獨立指標型態去宣告Array,就會變成
"Array是一個指標,指向一維 int 的陣列",而我們知道指標
本身就可以當做一維的陣列,那麼是不是就成了"Array是一個二維
的int陣列"?
對了!這正是我們要的!問題是怎麼讓'*'成為獨立指標型態,
不會去修飾前面的int識別字?答案是使用括號:
int (*Array)[20] = new int [10][20];//這是正解!

但問題又來了, new 運算子可以使用 new int [m][n],但
int (*Array)[20] 的 [20]卻沒辦法以 [n] 來取代,所以就
沒辦法做到不定大小的宣告了。所以這只能算是小班的答案,
要做到不定大小的動態多維宣告,加上 STL 的運用,是不錯
的想法。

《中班》vector 模板的運用
vector *array=new vector[m];
for (int i=0; i
嘿嘿...不錯吧!?不定大小的二維陣列,而且每個維度還
可以隨時調整大小喔!
不過還是有缺點ㄟ!!那行 for loop 看起來有點礙眼,不能
拿掉嗎?拿掉的話,基本上Array 還是二維陣列,但第二維
並沒有預留空間放東西你可以用push.back等成員函式來增加
空間和存放data,但不能在還沒有空間時使用像
array[5][3]=3; 這種陣列的存取方式。沒更好的方法了嗎?
vector 不是有預留空間大小的建構子嗎?像一維的宣告:
vector *Array= new vector (n);
//這不是預留了 n 個元素的陣列了嗎?
只可惜,這是一維的宣告,若你嘗試做這樣的宣告:
vector *Array= new vector [m](n);
編譯器會給你無情的嘲諷:陣列不能呼叫帶參數的建構子!
這是很令人失望的!為十麼不行?不是邏輯的問題,或許下
一版本的C++會可以這樣宣告吧!但為今之計只能自力救濟
了。

《大班》使用模板在模版中
仔細觀察下面的宣告:
vector > Array(m, vector(n));

不用懷疑!這是相當於宣告一個動態二維不定大小的 int Array[m][n];
不相信的話你可以在m,n範圍內存取 Array[i][j] 看看。
若你能一眼看出這是在幹嘛,那麼你早已超出大班的程度了!
若你暫時不知所云,也沒關係,你可以安全的使用它帶給你的好處。
只是你也只好留在大班留班查看了 ^_^

解釋這個宣告,其實不難,但首先你要對模版的使用有相當的了解,當然
還要對 vector 模版的建構子不能陌生。這樣子自然很容易可以看得懂它。
了然於胸了嗎?恭喜你,大班可以畢業了 ^_@


註:大班的答案是Duncan在練功房提出的解答,注意到兩個
兩個角括號中間的空白了嗎?(> >)
               ^-------這裡要有空白
不加空白的話會被語法解析為右移運算子。 

Sunday, January 22, 2012

Twitter如何在數千台伺服器上快速部署程式碼?

轉自
http://www.inside.com.tw/2010/07/17/how-twitter-deploys-application-to-thousands-of-servers


答案是:用BT,也就是你我應該都很熟悉的BitTorrent。
對於網站經營者、創業者來說,延展性的問題是在網站流量成長過程中勢必會面對的問題,如何建立一個具有延展性的架構(scalable architecture)便是在規劃網站事業過程中不可或缺的專業知識。
如果服務本身的功能性合乎使用者需求,卻因為架構、程式效能、資料庫效能的問題導致服務成長出現瓶頸,如何評估、分析網站效能瓶頸?釐清問題後如何找出對應的解決方案,可以思考的相關議題可能包括:
  • 如何有效率地釐清問題?從使用者端的數據(讀取時間)或是從伺服器端的log檔案、硬體的負載率?
  • 網站效能瓶頸是出現在Client或Server端?是資料庫撐不住還是程式效能不好?是Request太多還是檔案太大?
  • Web Server、DB server如何擠出更多的資源?擠不出資源後如何擴展?擴展後會遇到什麼問題?
參考國外知名網站在架構上的作法是很好的一種方式,儘管服務的規模可能無法相比,但根據「正確的作法與經驗」踏出對的第一步,肯定是有助於突破網站營運的效能瓶頸。
Twitter身為全球最大的微網誌服務,運用數千台的伺服器提供服務給來自全球各地的使用者,然而每當網站內容、應用程式有更新時,如何盡可能地在越短的時間內將程式碼部署(deploy)到所有的伺服器便是相當重要的課題。
Twitter的開發部落格上的一篇文章:「Murder: Fast datacenter code deploys using BitTorrent」分享了Twitter如何持續改善應用程式的部署流程,在過去Twitter使用Capistrano部署應用程式,Capistrano是許多Ruby/Rails使用者(當然也有其他語言的開發人員會使用)用來部署程式碼的一個開源專案,開發人員在部署程式碼的過程都可以透過自動化的部署流程來簡化經常重複的動作,尤其在專案必須同時部署到多台應用程式伺服器時會特別方便。
Twitter在早期便依賴Capistrano來進行應用程式的部署,每當有新版本的程式碼需要釋出時,Capistrano會根據預設好的各種設定、流程到Twitter所有的伺服器上進行更新的動作,在過去伺服器還不多的情況下一切都很美好,但隨著Twitter伺服器數量的成長,到了幾百台伺服器時,事情已經不再像過去一樣美好,甚至到後來擁有數千台伺服器時,更新的作業會耗費40分鐘。
Twitter針對這個問題,認為問題的關鍵在於:使用集中式的系統,也就是所有的伺服器要輪流排隊到同一台版本控制系統上進行程式碼更新。Twitter最初的想法是將版本控制系統也做出分散式的架構,伺服器的程式碼更新就可以分散到不同的機器來壓縮部署時間,但事實上版本控制系統即使分散在多台伺服器上,也同樣會有這些伺服器要更新檔案的時間。因此Twitter發現或許是需要一個完全去中心化、最好像是BitTorrent,利用P2P的特色讓所有的節點都可以協助進行程式碼的更新。
以結果來看,在採用了BitTorrent的方式來更新程式碼後,部署的時間從40分鐘大幅減少到只要12秒鐘!實在是非常驚人的改善,數千台伺服器的程式碼居然只要短短12秒鐘就能完成。
Twitter也將此次部署流程改善的成果分享出來,專案名稱叫做Murder,如果對於技術細節有興趣的讀者,可以再進行深入的研究;筆者簡單摘錄幾個重點如下:
  • Murder是以BitTornado為基礎開發出來的(BitTornado是某一種BitTorrent client)
  • Murder的定位是「協助我們快速的將檔案部署到大批伺服器上」
  • 利用BitTorrent的部署方式可避免防火牆的問題、擁有非常快的傳輸速度
  • 實際的部署程式碼是搭配Capistrano進行,網頁上有很清楚的說明
以下是Twitter的架構工程師Larry Gadea談Murder的影片:
http://vimeo.com/11280885

Monday, November 21, 2011

[轉錄]如何客製化 Google Nexus S 的 Kernel

轉自http://www.ur-solution.com/?p=26


Google Nexus S 使用的是原生的 android 作業系統,不像各家廠商的手機,經過大量的客製化,所以這個手機可以說環境最單純、乾淨、簡潔的系統了,我們在進行 Android 驅動程式 Porting 時,都會先拿這隻手機來測試,所以我們會要重新編譯這個手機的 Linux Kernel,在開始之前,首先我們事先準備一些環境,先下載 Android NDK,如下:

wget http://dl.google.com/android/ndk/android-ndk-r6b-linux-x86.tar.bz2
tar -jxf android-ndk-r6b-linux-x86.tar.bz2
export ARCH=arm
export CROSS_COMPILE=$(pwd)/android-ndk-r6b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-

接者我們要安裝 SDK:

wget http://dl.google.com/android/android-sdk_r12-linux_x86.tgz
tar -zxf android-sdk_r12-linux_x86.tgz
android-sdk-linux_x86/tools/android update sdk -u -t platform-tool
export PATH=$PATH:$(pwd)/android-sdk-linux_x86/platform-tools

現在我們可以開始進行編譯的工作,要編譯 Nexus S 的 kernel, 首先我們要取得 Samsung Nexus S 的 Kernel tree , 請執行:
git clone -b devrom-2.6.35 https://github.com/cgjones/samsung-android-kernel
cd samsung-android-kernel

接下來我們要設定 Kernel ,請執行:

make herring_defconfig

在開始編譯之前,我們先來看看手機上的 Kernel 版本資訊,請執行:

adb shell cat /proc/version
—–會得到以下的資訊
Linux version 2.6.35.7-ge382d80 (android-build@apa28.mtv.corp.google.com) (gcc v
ersion 4.4.3 (GCC) ) #1 PREEMPT Mon Feb 7 18:29:34 PST 2011

其中有一項很重要的資訊:2.6.35.7 ,這是我們 Kernel 的 版本。你要先確定使用的 kernel 版本是否正確,請執行:

shanchieh@ubuntu:~/nexus_s/samsung-android-kernel$ make kernelversion
2.6.35.7

很好,我們現在使用的也是 2.6.35.7。在版本後面有一個資訊:-ge382d80(2.3.4) (如果你的 OS 是 2.3.3 ,則會是:-g1d030a7 ),請將這個資訊寫入到 .scmversion 檔案中,請執行:

echo -ge382d80 > .scmversion
現在我們可以來開始編譯 kernel ,請執行:

make -j$(($(grep -c processor /proc/cpuinfo) * 3 / 2))

-j 這個參數後要接一個數字,例如 -j2 , -j4,等… 意思是說你同時要使用幾個核心來編譯。根據每一個人的環境不同,當然會不一樣,所以我們用一個參數來取得你目前硬體的核心數目。

編譯的過程中,我們先來看看 Nexus S 中的 boot 是在哪一個分割區中,請執行:

shanchieh@ubuntu:~$ adb shell cat /proc/mtd | awk -F’[:"]‘ ‘$3 == "boot" {print $1}’
mtd2
現在我們知道是放在 mtd2 的分割區中。在更換之前,我們先將手機上的 boot 保存下來,請執行:

shanchieh@ubuntu:~$ adb shell
# su
# dd if=/dev/mtd/mtd2 of=/sdcard/boot.img bs=4096
2048+0 records in
2048+0 records out
8388608 bytes transferred in 1.232 secs (6808935 bytes/sec)
# exit
# exit
這時在 /sdcard 之中。就會有一個 boot.img 的檔案。

請執行: adb pull /sdcard/boot.img 將這個檔案保存到我們的電腦中。

好。現在我們要來產生新的 boot.img 了,請執行:

git clone https://github.com/glandium/unbootimg.git
git clone git://git.linaro.org/android/platform/system/core.git
gcc -o unbootimg/unbootimg unbootimg/unbootimg.c core/libmincrypt/sha.c -Icore/include -Icore/mkbootimg
gcc -o mkbootimg core/mkbootimg/mkbootimg.c core/libmincrypt/sha.c -Icore/include
gcc -o fastboot core/fastboot/{protocol,engine,bootimg,fastboot,usb_linux,util_linux}.c core/libzipfile/{centraldir,zipfile}.c -Icore/mkbootimg -Icore/include –lz

這個時候就會產生 fastboot 跟 mkbootimg 兩個執行檔。

還記得剛剛我們備份下載的 boot.img 嗎?現在我們將這個檔案解開,請執行:

unbootimg/unbootimg boot.img

過程中會告訴你error ,沒關係,不用理會,還是可以順利解開,如下:
section sizes incorrect
kernel 1000 2b1b84
ramdisk 2b3000 22d55
second 2d6000 0
total 2d6000 800000
…but we can still continue

解開之後,會有三個檔案。

boot.img-mk, containing the mkbootimg options required to produce a working boot image,
boot.img-kernel, containing the kernel image,
boot.img-ramdisk.cpio.gz, containing the gzipped ramdisk, which we will reuse as-is.

好,現在我們要替換我們自己編譯的 kernek 了。請執行:

eval ./mkbootimg $(sed s,boot.img-kernel,samsung-android-kernel/arch/arm/boot/zImage, boot.img-mk)

現在我們使用 adb 來進行 fastboot

adb reboot bootloader

這個時候,你的手機應該進入到 fastbook 模式,如下圖:
IMG_0066

請執行: ./fastboot boot boot.img
或出現如下的訊息:

downloading ‘boot.img’…
OKAY [ 0.xxxs]
booting…
OKAY [ 0.xxxs]
finished. total time: 0.xxxs
這個時候手機會重新開機,開機就是使用我們剛剛編譯好的 kernel ,我們要如何驗證手機的 kernel 真的是我們自己編譯的呢?很簡單,在手機中執行:選單->設定->關於手機,就可以看到 kernel 的資訊,如下圖:

IMG_0067
但是手機下次你重新開機時, kernel 還是舊的,因為我們沒有燒入到手機的 ROM 中。如果要永久替換,請執行:
adb reboot bootloader
./fastboot flash boot boot.img
會出現如下的訊息:

sending ‘boot’ (2904 KB)…
OKAY [ 0.xxxs]
writing ‘boot’…
OKAY [ 0.xxxs]
finished. total time: 0.xxxs

再執行 ./fastboot reboot 進行重新開機 ,這樣就將手機中的 Kernel 換成我們自己編譯的了

飛鳥集 - 泰戈爾


世界對著它的愛人,把它浩翰的面具揭下了。
它變小了,小如一首歌,小如一回永恆的吻。
The world puts off its mask of vastness to its lover.
It becomes small as one song, as one kiss of the eternal.

有一次,我們夢見大家都是不相識的。
我們醒了,卻知道我們原是相親相愛的。
Once we dreamt that we were strangers.
We wake up to find that we were dear to each other.

神等待著人在智慧中重新獲得童年。
God waits for man to regain his childhood in wisdom.

創造的神秘,有如夜間的黑暗--是偉大的。
而知識的幻影卻不過如晨間之霧。
The mystery of creation is like the darkness of night--it is great.
Delusions of knowledge are like the fog of the morning.

光明如一個裸體的孩子,快快活活地在綠葉當中遊戲,它不知道人是會欺騙的。
The light that plays, like a naked child, among the green leaves happily
knows not that man can lie.

你微微地笑著,不同我說什麼話。而我覺得,為了這個,我已等待得很久了。
You smiled and talked to me of nothing
and I felt that for this I had been waiting long.

水裡的游魚是沉默的,陸地上的獸類是喧鬧的,空中的飛鳥是歌唱著的。
但是,人類卻兼有海裡的沉默,地上的喧鬧與空中的音樂。
The fish in the water is silent, the animal on the earth is noisy,
the bird in the air is singing.
But Man has in him the silence of the sea,
the noise of the earth and the music of the air.

那想做好人的,在門外敲著門;那愛人的看見門敞開著。
He who wants to do good knocks at the gate;
he who loves finds the gate open.

「可能」問「不可能」道:「你住在什麼地方呢?」
它回答道:「在那無能為力者的夢境裡。」
Asks the Possible to the Impossible, Where is your dwelling-place?
In the dreams of the impotent, comes the answer.

如果你把所有的錯誤都關在門外時,真理也要被關在門外面了。
If you shut your door to all errors truth will be shut out.

一個憂鬱的聲音,築巢於逝水似的年華中。
它在夜裡向我唱道:「我愛你。」
One sad voice has its nest among the ruins of the years.
It sings to me in the night, ---I loved you.

「誰如命運似的催著我向前走呢?」
「那是我自己,在身背後大跨步走著。」
Who drives me forward like fate ?
The Myself striding on my back.

我們的名字,便是夜裡海波上發出的光,痕跡也不留就消失了。
Our names are the light that glows on the sea waves at night
and then dies without leaving its signature.

鳥翼上繫上了黃金,這鳥便永不能再在天上翱翔了。
Set the bird's wings with gold and it will never again soar in the sky.

不要說:「這是早晨」,別用一個「昨天」的名詞把它打發掉。
你第一次看到它,把它當作還沒有名字的新生孩子吧。
Do not say, "It is morning," and dismiss it with a mane of yesterday.
See it for the first time as a new-born child that has no name.

雨點向茉莉花微語道:「把我永久地留在你的心裡吧。」
茉莉花嘆息了一聲,落在地上了。
The raindrop whispered to the jasmine, "Keep me in your heart for ever."
The jasmine sighed, "Alas," and dropped to the ground.

他們點了他們自己的燈,在他們的寺院內,吟唱他們自己的話語。
但是小鳥們卻在你的晨光中,唱著你的名字,--因為你的名字便是快樂。
They light their own lamps and sing their own words in their temples.
But the birds sing thy name in thine own morning light, --- for thy name is joy.

總有一天,我要在別的世界的晨光裡對你唱道:
「我以前在地球的光裡,在人的愛裡,已經見過你了。」
Some day I shall sing to thee in the sunrise of some other world,
I have seen thee before in the light of the earth, in the love of man.


「我相信你的愛。」讓這句話做我的最後的話。

Let this be my last word, that I trust thy love.

Get google nexus S kernel source code(git)


  • Get git source tree
    git clone http://android.googlesource.com/kernel/samsung.git
  • Create new branch, anndy
    git checkout --track -b anndy origin/android-samsung-2.6.35-gingerbread
  • Switch branch (if you want)
    git checkout  BRANCH_NAME




Sunday, November 20, 2011

To debug raw input event

frameworks/base/services/input/InputReader.cpp


// Log debug messages for each raw event received from the EventHub.#define DEBUG_RAW_EVENTS 1
// Log debug messages about touch screen filtering hacks.#define DEBUG_HACKS 1
// Log debug messages about virtual key processing.#define DEBUG_VIRTUAL_KEYS 1
// Log debug messages about pointers.#define DEBUG_POINTERS 1
// Log debug messages about pointer assignment calculations.#define DEBUG_POINTER_ASSIGNMENT 1
// Log debug messages about gesture detection.#define DEBUG_GESTURES 1

To Disable light sensor

disable light sensor
1.adb shell
2.su
3.cat /proc/bus/input/devices
    find out which one is light sensor
3.echo 0 > /sys/devices/virtual/input/input4/enable

Saturday, November 19, 2011

Android 4.0 on Nexus S(base on AOSP)

在15號 AOSP放出4.0的source code後
經過幾天的努力
終於...可以進入android 4.0的介面了!
進入的瞬間...超感動的!!!
不過很多HW都還不能動
最著名的Face unlock也不能用(camera 還沒porting...)
連觸控都還有點問題
還有的搞XD


有圖有真相
https://plus.google.com/u/0/photos/101888505277693924282/albums/5676631313143648721

Friday, November 18, 2011

夢想

將妳輕輕地捧起
再深埋我心田
種下我們相逢的伏筆
在一個陽光燦爛的午後

Thursday, November 17, 2011

Partition Alignment on linux

copy from : http://www.nuclex.org/blog/personal/80-aligning-an-ssd-on-linux




Partition Alignment

If the partitions of a hard drive aren't aligned to begin at multiples of 128 KiB, 256 KiB or 512 KiB (depending on the SSD used), aligning the file system is useless because everything is skewed by the start offset of the partition. Thus, the first thing you have to take care of is aligning the partitions you create.
A spindle with three discs with a red ring superimposed on each of the discs
A cylinder.
A spindle with three discs with a red pie slice superimposed on each of the discs
A sector.
Traditionally, hard drives were addressed by indicating the cylinderhead and sector at which data was to be read or written. These represented the radial position, the drive head (= platter and side) and the axial position of the data respectively. With LBA (logical block addressing), this is no longer the case. Instead, the entire hard drive is addressed as one continuous stream of data.
Linux' fdisk, however, still uses a virtual C-H-S system where you can define any number of heads and sectors yourself (the cylinders are calculated automatically from the drive's capacity), with partitions always starting and ending at intervals of heads x cylinders. Thus, you need to choose a number of heads and sectors of which the SSD's erase block size is a multiple.
I found two posts which detail this process: Aligning Filesystems to an SSD's Erase Block Size and Partition alignment for OCZ Vertex in Linux. The first one recommends 224 heads and 56 sectors, but I can't quite understand where those numbers come from, so I used the advice from the post on the OCZ forums with 32 heads and 32 sectors which means fdisk uses a cylinder size of 1024 bytes. And because fdisk partitions in units of 512 cylinders (= 512 x heads x sectors) fdisk's unit size now happens to be an SSD's maximum erase block size. Nice!
To make fdisk use 32 heads and 32 sectors, remove all partitions from a hard drive and then launch fdisk with the following command line when you create the first partition:
fdisk -S 32 -H 32 /dev/sda
The OCZ post also recommends starting at the second 512-cylinder unit because the first partition is otherwise shifted by one track. Don't ask me why :)
Here's how I partitioned my SSD in the end:
Screenshot of a linux console where fdisk reports 32 heads and 32 sectors
For a normal hard drive, I'd probably use 128 heads and 32 tracks now to achieve 4 KiB boundaries for my partitions.

RAID Chunk Size

If you plan on running a software RAID array, I've seen chunk sizes of 64 KiB and 128 KiB being recommended. This can be specified using the --chunk parameter for mdadm, eg.
mdadm --create /dev/md3 --level=1 --chunk=128 --raid-devices=2 /dev/sda3 /dev/sdb3
Probably the larger chunk size is more useful if you are storing large files on the RAID partition, but I haven't found any advice which included benchmarks or at least a solid explanation yet.

File System Alignment

Now that the partitions have been taken care of, the file systems need to use proper alignment as well. Generally all file systems use some kind of allocation blocks, usually with a size of 4 KiB. But increasing this size to 128 KiB (or even 512 KiB) would waste a lot of space since any file would use up memory in a multiple of that number.
Luckily, Linux file systems can be tweaked a lot. I'm using ext4, here the -E stride,stripe-width parameters control the alignment. The HowTos/Disk Optimization page in the CentOS wiki gives this advice:
The drive calculation works like this: You divide the chunk size by the block size for one spindle/drive only. This gives you your stride size. Then you take the stride size, and multiply it by the number of data-bearing disks in the RAID array. This gives you the stripe width to use when formatting the volume. This can be a little complex, so some examples are listed below.
For example if you have 4 drives in RAID5 and it is using 64K chunks and given a 4K file system block size. The stride size is calculated for the one disk by (chunk size / block size), (64K/4K) which gives 16K. While the stripe width for RAID5 is 1 disk less, so we have 3 data-bearing disks out of the 4 in this RAID5 group, which gives us (number of data-bearing drives * stride size), (3*16K) gives you a stripe width of 48K.
The Linux Kernel RAID wiki offers further insight:

Calculation

  • chunk size = 128kB (set by mdadm cmd, see chunk size advise above)
  • block size = 4kB (recommended for large files, and most of time)
  • stride = chunk / block = 128kB / 4k = 32kB
  • stripe-width = stride * ( (n disks in raid5) - 1 ) = 32kB * ( (3) - 1 ) = 32kB * 2 = 64kB
If the chunk-size is 128 kB, it means, that 128 kB of consecutive data will reside on one disk. If we want to build an ext2 filesystem with 4 kB block-size, we realize that there will be 32 filesystem blocks in one array chunk.
stripe-width=64 is calculated by multiplying the stride=32 value with the number of data disks in the array.
A raid5 with n disks has n-1 data disks, one being reserved for parity. (Note: the mke2fs man page incorrectly states n+1; this is a known bug in the man-page docs that is now fixed.) A raid10 (1+0) with n disks is actually a raid 0 of n/2 raid1 subarrays with 2 disks each.
So these are the stride and stripe-width parameters I'd use:
  • Intel SSDs with an erase block size of 128 (or 512 KiB -- Intel isn't quite straightforward with this, see the comments section for a discussion on the subject - if anyone from Intel is reading this, help us out! ;-)) that are not part of a software RAID:
    -E stride=32,stripe-width=32
  • OCZ Vertex SSDs with an erase block size of 512 KiB that are not part of a software RAID:
    -E stride=128,stripe-width=128
  • Normal hard drives that are not part of a software RAID
    trust the defaults
  • Any software RAID:
    -E stride=raid chunk size / file system block size,stripe-width=raid chunk size x number of data bearing disks
Thus, I set up the file systems on the Intel SSD like this:
mkfs.ext4 -b 1024 -E stride=128,stripe-width=128 -O ^has_journal /dev/sda1
mkfs.ext4 -b 4096 -E stride=32,stripe-width=32 /dev/sda3
mkfs.ext4 defaulted to 1024 byte allocation units on my boot partition, so I adjusted the stride up to 128 KiB according to the advice from the CentOS wiki. The alignment of my boot partition is probably not of any relevance because the system will read maybe 10 files from it and not modify anything, but I wanted to stay consistent :)


國境之南


國境之南

詞:嚴云農

如果海會說話 如果風愛上砂
如果 有些想念遺忘在漫長的長假
我會聆聽浪花 讓風吹過頭髮
任記憶裡的愛情在時間潮汐裡喧嘩

非得等春天遠了夏天才近了
我是在回首時終於懂得(也許天氣永遠會那麼熱)
當陽光再次回到那 飄著雨的國境之南
我會試著把那一年的故事 再接下去說完

當陽光再次離開那 太晴朗的國境之南
妳會不會把妳曾帶走的愛 在告別前用微笑全歸還

海很藍 星光燦爛 我仍空著我的臂彎
天很寬 在我獨自唱歌的夜晚
請原諒我的愛 訴說的太緩慢

Sunday, November 13, 2011

HOWTO: Install Linux Kernel 2.6.35 on Ubuntu 10.04 (Lucid) from Ubuntu 10.10 (Maverick) The Easy Way

https://sites.google.com/site/lightrush/random-1/howtoinstalllinuxkernel2635onubuntu1004lucidfromubuntu1010mavericktheeasyway
1.
sudo apt-get update && sudo apt-get install linux-image-generic-lts-backport-maverick linux-headers-generic-lts-backport-maverick


2.reboot

Tuesday, November 08, 2011

Wednesday, August 10, 2011

Tuesday, May 03, 2011

functions trace

http://www.logix.cz/michal/devel/CygProfiler/

CygProfiler is a set of functions for use with gcc's -finstrument-functions option. See info page of gcc for details and description of this option.

To use it, compile your program with -finstrument-functions and link together with cyg-profile.c. Somewhere at the beginning of the program call cygprofile_enable() to start logging all function entries and exits into a logfile.

By default the name of the logfile is cyglog.$PID, but you can set a different one using cygprofile_setfilename(). To get current logfile name use cygprofile_getfilename(). To see if logging is enabled use cygprofile_isenabled(). You can stop logging by calling cygprofile_disable().

Note that subsequent enabling of logging will overwrite the previous log with the same name!

After you have created a logfile run cyg-resolve.pl with the program name that created the logfile as a first argument and the logfile name as a second argument. On stdout you'll see a log of all instrumentalized functions invoked while logging was enabled.

用 Graphviz 可视化函数调用

为了捕获并显示调用图,您需要 4 个元素:GNU 编译器工具链、Addr2line 工具、定制的中间代码和一个名为 Graphviz 的代码。Addr2line 工具可以识别函数、给定地址的源代码行数和可执行映像。定制的中间代码是一个非常简单的工具,它可以减少对图形规范的地址跟踪。Graphviz 工具可以生成图形映像。整个过程如图 1 所示。