2009年12月29日 星期二

RamDisk和Junction

在編譯project時,因會要編譯超多的檔案,所以,對I/O的讀取會相當多次~

今天由同學那裡知道原來有一個免費的軟體,叫RamDisk可以把記憶體當作硬碟來使用~

這樣就可以減少對硬碟的讀取了!不過,缺點是每一次重新開機後,資料都會不見!(不過,這可能也是優點,這就要看資料夾怎麼使用了!)

不過,還好,我有用SVN版本控制,可以在每一次要做project前,才把資料由svn把原始碼還原,所以整體上的效能和方便性還算不錯!

以下是我做的步驟~

因為Build這一個資料夾裡面放的是compiler的產物,為了要加速編譯的過程,所以,要建立一個RamBuild資料夾,而它是放在RamDisk上,而在原本的位置的會建立一個新的Build,而它是hard link到RamBuild這一個資料夾,換句話說,這樣就可以騙過系統,當它在存取Build資料夾時,實際上是在存取在RamDisk上的RamBuild資料夾,如此一來,就可以加快編譯的速度啦~

而在Linux下有hard link的功能,但是,在windows下確沒有hard link的功能,這個時候,我們要用junction的功能,它可以讓XP具有hard link的功能

1. 暫時把d:\下的Build改名為Build_bak,並同時建立一個新的Build資料夾
% move Build Build_bak && mkdir Build

2. 在RamDisk上建立一個新的資料夾RamBuild,並且把Build資料夾hard link到RamBuild資料夾
% mkdir r:\RamBuild && junction Build r:\RamBuild

3. 把所有在Build_bak資料夾下的內容複製到Build資料夾下
% xcopy Build_bak\*.* Build\ /k /e /q /y

4. 為了計算編譯的時間,所以,預先取得編譯前的時間
% set OLDTIME=%time%

5. 開始編譯,其中,若要使用到其它bat檔,當它執行完時,再回來繼續執行剩下的程式碼,則必需要使用到call,若沒有使用call的話,而直接使用bat檔的話,則當bat檔執行完後,馬上結束,不會執行這一個bat檔剩下的程式碼
% cd Build && call MultiMake.bat

6. 取得編譯完後的時間
% set NEWTIME=%time%

7. 把編譯完成之後的結果複製到Build_bak資料夾中,這裡要注意的是,這裡的Build資料夾,因為透過junction,同時也代表在RamDisk下的RamBuild資料夾,也就是存放compiler後的產物放的位置
% cd .. && xcopy Build\*.* Build_bak\ /k /e /q /y

8. 移除Build資料夾hard link到RamBuild資料夾的特性,並且把Build_bak改名為Build
% junction -d Build && move Build_bak Build

9. 刪除在RamDisk下的RamBuild資料夾,另外,因為XP沒有deltree,必需要另外到這一個頁面下載
% deltree /y r:\RamBuild

10. 顯示編譯前的時間與編譯後的時間
% echo Start Time %OLDTIME%
% echo End   Time %NEWTIME%


以下是完整的程式碼,在bat檔中,rem是表示註解的意思
fastmake.bat
rem rename Build to Build_bak
move Build Build_bak && mkdir Build

rem create a new file r:\RamBuild, if success hard link Build to r:\RamBuild in the RamDisk
mkdir r:\RamBuild && junction Build r:\RamBuild

rem copy all the Build_bak file to Build
xcopy Build_bak\*.* Build\ /k /e /q /y

rem get the current time before compiler
set OLDTIME=%time%

rem compiler...
cd Build && call MultiMake.bat

rem get the current time after compiler
set NEWTIME=%time%

rem copy the result to Build_bak
cd .. && xcopy Build\*.* Build_bak\ /k /e /q /y

rem delete the junction folder and renmae Build_bak to Build
junction -d Build && move Build_bak Build

rem delete all the file in the r:\RamBuild
deltree /y r:\RamBuild

rem show the time before compiler
echo Start Time %OLDTIME%

rem show the time after compiler
echo End   Time %NEWTIME%


MultiMake.bat
因為,不知道什麼原因,必需要重覆nmake多次才會成功,因此,在這裡設定最大try 20次
rem because there is no-reason problem, we have nmake multi-time

@echo off

rem set the MaxTry
set MaxTry=20

rem set the current count to record the TryCount
set Count=0

:start
rem when Count is less or equal than MaxTry, Count will plus one and nmake again
rem If the nmake is fail, the process will go to start label.
rem If the nmake is success, the process will go to next line instead of going to start label.

if %Count% LEQ %MaxTry% set /A Count=Count+1 && echo this is %Count% times && nmake || goto start

IF %Count% GTR %MaxTry% (
  echo exceed MaxTry, compiler fail!!!!!.
) ELSE (
  echo Compiler success!!!!!.
)

:end


[2010.01.07 補充]
也可以使用RamDisk來加快,瀏覽器的存取~

1. 首先需要先安裝 RAMDisk 軟體,把記憶體拿來劃成硬碟使用。可以參考這裡

2. 我自己是把 RAMDisk 設成 R:\

Internet Explorer
3. 開啟 IE > 工具 > 網際網路選項 > 設定 > 移動資料夾 > 指向 R:\IECache

4. 重新啟動 IE

Firefox
5. 開啟 Firefox 後,在網址列上敲上 about:config

6. 新增 > 字串 > 鍵入 "browser.cache.disk.parent_directory" > 填上字串值 "R:\FirefoxCache"

7. 確認是否有browser.cache.disk.smart_size_cached_value,若沒有新增為數值類型,並且填上225280為其數值

8. browser.cache.disk.smart_size.enabled確定為true

8. 重新啟動 Firefox

9. 在網址列寫入about:cache
可以看到目前cache的設定

Chrome
8. 直接在Chrome在捷徑加上一個參數: --disk-cache-dir=R:\ChromeCache ("R:\ChromeCache"位置可自訂)

現在 IE, Firefox, Chrome 瀏覽時的暫存檔案都會放在 RAMDisk R:\ 上,理論上是比暫存在硬碟上快些。有興趣的朋友,不妨嘗試看看囉~

[2010.01.16 補充]
以下的bat檔案,主要是在編譯不同的檔案的時候,要使用不同的compiler,這個時候要用junction來指到不同的compiler,這一個bat可以讓使用者選擇要建立Junction資料夾或是移除Junction資料夾~

@echo off

rem build a hard link from DEVTLS to target-directory
rem redirect-DEVTLS target-directory
rem Example: redirect-DEVTLS D:\DEVTLS_Tool\NTC_DEVTLS


set /P UserSelect=1. Redirect DEVTLS 2. Remove Junction Direct (D:\DEVTLS):
if %UserSelect% EQU 1 goto Redirect
if %UserSelect% EQU 2 goto Undirect
echo Your choice out of option
goto end

:Redirect
echo ==========Redirect option==========
set /P UserInput=Please input the target DEVTLS directory(ex: D:\DEVTLS_Tool\NTC_DEVTLS):

rem test the DEVTLS exist or not
IF EXIST DEVTLS (
rem DEVTLS exists, remove junction directory
junction -d DEVTLS || goto fail
echo remove the original junction directory successfully
)

rem Test the target directory
IF EXIST %UserInput% (
rem If exists, create junction directory from %UserInput% to DEVTLS
junction DEVTLS %UserInput% || goto fail
echo build create junction directory form %UserInput% to DEVTLS successfully
goto success
) ELSE (
echo target %UserInput% doesn't exist
goto fail
)

:Undirect
echo ==========Undirect option==========
rem test the DEVTLS exist or not
IF EXIST DEVTLS (
rem DEVTLS exists, remove junction directory
junction -d DEVTLS || goto fail
echo remove the original junction directory successfully
goto success
) ELSE (
echo DEVTLS doesn't exist
goto fail
)

:success
goto end

:fail
goto end

:end
echo End of Bat File...
pause


[2010.05.11 補充]
@ECHO OFF

REM build a hard link from DEVTLS to target-directory
REM redirect-DEVTLS target-directory
REM Example: redirect-DEVTLS D:\DEVTLS_Tool\NTC_DEVTLS

REM Initial the Junction folder
REM If mark SET JunctionTarget, this bat will ask user the JunctionTarget when proceduring

SET JunctionTarget=

REM ===========================================================================
REM ==== GET&SET SOURCE AND TARGET PATH (DO NOT MODIFY) =======================

IF "%JunctionTarget%" NEQ "" GOTO JunctionProcedure
ECHO ========== SET JunctionTarget Folder ==========
SET /P JunctionTarget=Please input the target directory (ex: D:\DEVTLS):

:JunctionProcedure
ECHO ========== User Selection ==========
ECHO 1. Redirect %JunctionTarget%
ECHO 2. Remove Junction Direct (%JunctionTarget%)
SET /P UserSelect=User Select:
IF %UserSelect% EQU 1 GOTO Redirect
IF %UserSelect% EQU 2 GOTO Undirect
ECHO Your choice out of option
GOTO End

:Redirect
ECHO ========== Redirect option ==========
SET /P JunctionSource=Please input the source directory(ex: D:\DEVTLS_Tool\NTC_DEVTLS):

REM test the %JunctionTarget% exist or not
IF EXIST %JunctionTarget% (
REM %JunctionTarget% exists, remove junction directory
junction -d %JunctionTarget% || GOTO Fail
ECHO Remove the original junction directory successfully
)

REM Test the source directory
IF EXIST %JunctionSource% (
REM IF exists, create junction directory from %JunctionSource% to %JunctionTarget%
junction %JunctionTarget% %JunctionSource% || GOTO Fail
ECHO Create junction directory form %JunctionSource% to %JunctionTarget% successfully
GOTO Success
) ELSE (
ECHO target %JunctionSource% doesn't exist
GOTO Fail
)

:Undirect
ECHO ========== Undirect option ==========
REM test the %JunctionTarget% exist or not
IF EXIST %JunctionTarget% (
REM %JunctionTarget% exists, remove junction directory
junction -d %JunctionTarget% || GOTO Fail
ECHO Remove the original junction directory successfully
GOTO Success
) ELSE (
ECHO %JunctionTarget% doesn't exist
GOTO Fail
)

:Success
GOTO End

:Fail
GOTO End

:End
ECHO End of Bat File...
PAUSE


參考資料:
Gavotte Ramdisk 免費「虛擬硬碟」使用教學
密技 / 塞爆4G記憶體! Gavotte Ramdisk 32 bit XP
Junction v1.05
Gavotte RAMDisk
用gavotte的ramdisk碰到問題~求解
用mklink與junction建立資料夾連結
拿 RAMDisk 加速 Firefox, IE 的瀏覽速度
Gavotte Ramdisk 使用心得
介紹好用工具:Junction ( Windows 版的 symbolic link )

沒有留言: