PC 當機的原因

前幾天,我那堪稱身強體壯的電腦居然當機了!這個問題源自於那天陪女兒去光南買文具時,意外看到 NBA2K14 的海報,它才賣 880 NTD 耶…, 一時衝動我就“支持原版“了。(不想支持原版的,請找大陸同胞就對了。)誰知這個遊戲讓我一跑就當機,從此開啟了我為期兩週的修電腦夢魘。

新遊戲導致當機當然先懷疑軟體,上網 Google 了一下,確實有類似的災情。這些網站上的好心人, 除了教人檢查CPU、顯示卡、記憶體、電源供應器等硬體之外,聽起來最合理的解法, 就是更新顯示卡的驅動程式和安裝 visual C run time library.

雖然這些試過了都沒有效果,但是過程中還是學到很多東西。例如 Everest 現在可以測試 PC 效能, 有些人跟我一樣, 跑到 sinJulia, 畫面就不會動或是當機了. 也有人同樣是跑 Windows 體驗分數時出問題, 大約在跑 Direct 9 測試的時候當掉! (有人說先把 WinSAT 目錄清掉再跑, 但這對我也沒用.) 另外就是我跑 3D Mark 必當, 只是時間早晚而已! 有人和我一樣, 也有人跑一個禮拜沒事!

經過觀察, 我發現只要跑 WinSAT 或是 3D Mark 時, 電腦的風扇聲就會變大. 我想, 或許電腦在偷偷超頻吧? 或許這就是原因? 於是我到 BIOS 那邊去做各種設定, 此時我才知道華碩的 P8Z68 還真是愛偷跑, 光是在 BIOS 簡易設定裡把效能降到最低並沒有用, 每次重新開機必定至少偷跑個十幾 MHz. 即使把 Ai 超頻設為手動, 企圖禁止它偷跑; 由於設錯了其他東西, 它還是毫無人性地把 CPU 從 3.4 GHz 超到 4.4 GHz. 然後告訴我開不了機. 

原來把 memory clock rate 降低, 搭配 BCLK / PCIE 比例設高也不行. 嘗試了幾次後, 最後的結論是: Ai 仍舊設為手動, Memory 設為 1333MHz (雖然我買 1600 MHz), BCLK / PCIE = 100 (設太低也會開不了機), Turbo 倍頻設自動, 然後 CPU 就會乖乖地停在 3.4GHz 了.

畢竟中間當了那麼多次, 硬碟沒病也變有病了! 於是我把 C 槽備份後, 做了一個晚上的 check disk. 然後重灌一次 Win7. 雖然我先前都用得好好的, 但是有些小地方讓我不太滿意. 像是金山毒霸會導致 iPad 偵測不到 (disable 後就可以, 不用移除.), 而且它把別人的首頁綁架軟體關了, 自己卻占住了首頁! 這些雜七雜八的軟體 (快播, 金山…) 都會一直開 pop 視窗, 也讓人煩不勝煩. 乾脆就來個浴火重生吧!

果然, 經過鎖定 CPU 頻率, check disk 之後, Everest 可以順利跑完了. 重灌之後, 試玩了 NBA2K14 也沒再當機. 經過一番波折, 我大概歸納出以下的結論:

1. 跑 memtest86, 若是能跑完 1 個 pass (大概一個晚上),表示 memory 基本上沒問題.

2. 如果進到 BIOS, 或是看 Everest 的 5V, 12V 電壓大概也在 5V, 12V 附近, 那麼 power 也沒有問題.

3. 能跑完 3D Mark, 顯示卡大概也沒問題.

4. 確定電腦不會自行超頻, 設定完成後, 重新開機看一次有沒有變化.

5. 檢查硬碟很重要. 2TB 大小也是要花ㄧ個晚上, 但值得做!

以上分享自己當機的悲慘經驗, 希望大家都可以迅速地解決問題. 因為計劃趕不上變化, 本篇還有些插曲, 我另外再寫兩篇給大家參考.

Android 手機記憶體不足問題

有好一陣子, 手機都在抱怨記憶體不足的問題.  我用的 Galaxy Note 有 1GB DDR 和 16 GB FLASH.  如果是 DDR 不足, 可以用手機助手…等軟體把不用的 task 清掉, 這個問題較小. 比較大的問題是 NAND 切給 data 的空間不足, 這個就不是外插一張 SD 卡的問題了.

關於 data 的空間不足, 主要原因是 android  會把內建的 NAND 分成幾個 partitionm 像是 boot, system, data,cache…. 等等, 當然也有分更細的. 像是 [1] 説到的 9~10 個 partition. 總之, 使用者可以自由使用來安裝 APK 的空間沒有想像中得大.  即使內建的 NAND 還有很大的空間, 但是它未必能給 APP 安裝使用. 我的手機就只有 2GB 可以放自己安裝的 APP. 所以不只是我, 別人也會遇到這個問題, 常見的建議如下:

1. 不要安裝太多 APP.

2. 把 APP 安裝到外部 SD 卡上.

3. 到設定程式管理員那裡把 cache 清一清.

4. 把 datamedia 底下的多媒體檔案清掉.

5. 把佔用資源很多的 APP 清掉, 例如 Platinum 雖然是好物, 但是它自己也很肥.

6. root 後把用不到的韓國 APP 殺掉! 例如 reader hub…等等.

7. root 後把 datadalvik-cache 清掉.

8. root 後把 dalvik-cache 搬到 SD 卡. [4-6]

9. root 後把 NAND 重新 partition

經過身體力行之後, 發現 7 是最有用的. 因為我雖然把不用的 APP 移除了, 但 Android 把它們的 Dalik 檔案 (一堆 .dex) 都保留了下來. 當我把整個資料夾 500 多個檔案清空, 然後重新開機, 雖然 Android 又針對還存在的 APP 優化了一次, 我確多了 100MB 以上的空間出來. 那些下載檔案放不下的問題就沒有再出現了.

方法 8 雖然比 7 更好, 不過反應速度不知道會不會變慢? 我的外接 SD 是 class 10, 理論上可以應付. 等到 7 撐不住了再來用 8.

至於方法 9, 這招我是不敢用.

[ref]

1.Android/partitions

2. 2013-07-17 [Android] App怎麼使用最Smart?關於App使用與系統效能調校的8個小撇步!

3. [Android] 何謂 dalvik cache?

4. Mounts2SD – Storage & Memory

5. Moving Dalvik Cache to SD Card.

6. 小V精簡dalvik-cache, 增加空間

 

Smart pointer 小註解

Smart pointer 是為了解決要了記憶體沒有還 – 導致 memory leak, 或是記憶體已經還了還在用 – 導致當機的問題. 直覺上, 還個記憶體好像並非難事, 何必大費周章呢? 主要是由函數返回指標時, 我們不能確定要在外面還還是裡面? 例如 [2] 所說的, 不是我 new 的, 需要我 delete 嗎?

DataGenerator DataGen;
int* A = DataGen.GetData();
delete A; // Should do this?

為了解決這個問題, 我們需要比較聰明的指標. 在 C++11 和 Android 裡面, smart pointer 的定義略有不同. 在 C++ 的話, 可以分為 3 種, 分別是: 前者的 unique ptr, shared ptr, waek ptr . 而 Android 裡面分為 strong pointer 和 weak pointer 兩種. 它們的定義分別如下 [1-2]. 如果是 MFC, QT… 的話, 都還有定義別種的 smart pointer [5-6], 基本上大同小異.

pointer 定義
unique_ptr 確保一份資源(被配置出來的記憶體空間)只會被一個 unique_ptr 物件管理的 smart pointer;當 unique_ptr 物件消失時,就會自動釋放資源。
shared_ptr 可以有多個 shared_ptr 共用一份資源的 smart pointer,內部會記錄這份資源被使用的次數(reference counter),只要還有 shared_ptr 物件的存在、資源就不會釋放;只有當所有使用這份資源的 shared_ptr 物件都消失的時候,資源才會被自動釋放。
weak_ptr 搭配 shared_ptr 使用的 smart pointer,和 shared_ptr 的不同點在於 weak_ptr 不會影響資源被使用的次數,也就是說的 weak_ptr 存在與否不代表資源會不會被釋放掉。
strong pointer 等同於 C++ 11 的 shared pointer
weak pointer 弱指針只能指一個 object, 所以沒有 counter. 它只是提供一個地址, 甚至還不能調用 object 的 member function 或是 variable.

強指針 (strong pointer = sp) 和一般的 shared_ptr 一樣, 透過 counter 來記錄有多少 “人" 引用這個 object?如果每個人都用完了, counter 歸零之後就可以被 free.  [1,4]  而弱指針 (weak pointer = wp) 並不理會還有沒有人用, 只要自己用完就可以 delete 了. 當然, 只有在同時也沒有強指針指到它才會被 delete. 參考 [5] 的例子.

ref1, ref2, ref5 都是強指針 sp, ref3 是弱指針 wp. ref4 是 promote 過後的弱指針. 弱指針也不永遠是扶不起的阿斗, 它可以用 promote function 升級為強指針  (寫到這邊, 電視上正在演 “見龍卸甲", 劉德華救阿斗耶…).

// 先定義 class, Android 用的是 frameworksbaseincludeutilsRefBase.h

namespace android {

class RefTest : public RefBase {
public:
    RefTest(int32_t id) : mID(id) {
        printf(“RefTest ctor: %dn", mID);
    }
    virtual ~RefTest() {
        printf(“RefTest dtor: %dn", mID);
    }
    int32_t id() const {
        return mID;
    }
private:
    int32_t mID;
};
// 測試 strong pointer 的函數

int strong_pointer() {

    sp<RefTest> ref1 = new RefTest(1);
    sp<RefTest> ref5;
    {
        sp<RefTest> ref2 = new RefTest(2);
        ref5 = ref2; // comment this out and check when the destructor of ref2 is called,
                          // ref5 又參考了 ref2
    }
    wp<RefTest> ref3 = ref1; // 弱指針也可以指向強指針, 但強指針不能指向弱指針.
    sp<RefTest> ref4 = ref3.promote(); // 弱指針可以 promote 為強指針
    if (ref4 == NULL) {
        printf(“RefTest object is destroyedn“); // 強指針和弱指針都沒有人用, 就可以回收了. 但還不會發生.
    } else {
        printf(“RefTest object %d is still aroundn", // 此時還有人用
            ref4->id());
    }
    ref4 = NULL; // ref4 清掉, ref3 是弱指針不用管, ref1 還在用
    ref1 = NULL; // comment this out to check to check change in prints
                         // ref1 也不用了.
    ref4 = ref3.promote(); // ref1 清掉, ref4 清掉, 所以 ref4 這次應該 NULL 了.
    if (ref4 == NULL) {
        printf(“RefTest object is destroyedn");
    } else {
        printf(“RefTest object %d is still aroundn",
            ref4->id()); // 清掉了
    }
    printf(“Before return n");
    return 0;
} 
強指標的觀念帶有 counter, 似乎已經相當完備; 為什麼有強指針以後, 還要有弱指針? 甚至要那麼麻煩地去升級弱指針呢? 其實弱指針並不像它的名字那樣一無事處, 它也具有立刻把記憶體立即釋放掉的優勢. 在 “IOS5 ARC 完全手冊" [9] 的文件裡面, 它把弱指針的用途做了說明.
這次的 reference 特別多, 因此本來想簡單寫完, 不料化簡為繁, 又化繁為簡, 前後竟然跨了四天.

[ref]

1. Android智能指针使用方法介绍

2. 避免 memory leak:C++11 Smart Pointer

3. What are strong pointers and weak pointers

4. android smart pointer – [1] 的原文

5. Smart Pointers to boost your code

6. dhav’s blog

7. QT smart point 智能指针

8. C++内存管理

9. ios 5 arc完全指南

Slice vs Tile in H.265

在 H.265 (HEVC) 的規格裡面多一個名詞 tile, 本來我們講 tile 都是說 memory 的排法不要照 scan line, 而是以 Macroblock 為單位, 以節省記憶體頻寬. 不過這個名詞在 H.265 已經有了正式的定義. 首先, 回顧一下 H.264 的名詞. 可以根據下圖來區別 Coded Video Sequence, AU 和 NAL [1].

接下來看一下比較舊的 slice 的定義.

Slice 的下一層是 slice segment. 由一個 independent slice segment 開始, 接著一串 dependent slice segment. 在同一個 AU (access unit, 正好就是解出一張) 裡面, 可以有多個 slice segment. 下圖的每一個框框是一個 coding tree unit (CTU) , CTU 可以再切割成 coding tree blocks [2, 4].

Tile 的分法永遠是矩形的. 看到灰色的 independent segment就是一個 slice 的開頭, 後面白色的部分就是 depedent segments. 一個tile 可以包含多個 slice, 一個slice 也可以跨多個 tile. 不過還是要有一些規則.

首先記住 CTU 會組成 coding tree, 接著至少要滿足下面兩個條件之一:

1. 所有的 slice 的 CTU 都完整地在一個tile 內.

2. 所有的 tile 的 CTU 都完整地在一個 slice 內.

其中, 1 的條件也可以延伸為 “所有的 slice segment的 CTU 都完整地在一個tile 內. 比 2 的條件再更嚴格一點的話, 就是所有的 tile 的 CTU 都完整地在一個 slice segment內. 規格書說, 上述兩個條件也要至少滿足其中之一.

此外, 我們有 Y/U/V 三個平面 (plane), 如果 separate_colour_plane_flag = 0, 那麼表示大家的slice 都長一樣. 若是這個值等於 1, 表示三個平面可以有自己的 slice. 此時, 三個平面的資料在同一個 AU裡面可以交錯 (interleave). 但是同一個 plane id 裡面的 coded slice segment NAL unit 只能依照 tile order 遞增.

那 tile 有什麼用呢?它是可以平行處理的單位. 也就是說, decoder 可以同時對多個 tile 進行解碼. 以前我們要解完一個 slice, 才能再解下一個 slice, 否則也不知道下一個 slice 的 header 在哪裡?現在我們只要知道有幾個 tile, 就可以從 tile 的頭開始解碼. Tile 不像 slice 有 header, 所以不會又多一層 overhead.

那麼, 我們怎麼找到 tile 的開頭呢?從 bit stream 裡面可以找到這一段定義.

首先就看有沒有 enable tile (tiles_enabled_flag = 1), 有的話再看是不是均勻的大小 (uniform_spaciing_flag). 如果 tile 並不一樣大, 就分別讀出每一個 tile 的寬高. 雖然 bit stream 沒有直接講出寬高, 只要在畫面上下砍 column_width_minus1 刀, 橫切 row_height_minus1 刀就可以得到這些格子了.

在 [ref 3] 裡面, 有人提到 tile 可以做 ROI (region of interest, 不是 return on investment). 先畫一個 tile 放重點, 給比較高的 bit rate; 其他的小 tile 就給比較低的 bit rate. 由於 H.265 裡面拔掉了 H.264 的 FMO (flexible MB order),  所以光靠 slice 就不方便做這種匡出一塊矩形效果. 另外, 這邊有人吐槽 FMO 本來就是做 error concealment 用的, 不是 ROI 用的.

[REF]

1. H.264先進視訊編解碼標準

2. H.265 Spec.

3. I am littile confused about the tiles in HEVC. Can’t we achieve same parallelism using only slices?

4. HEVC – What are CTU, CU, CTB, CB, PB, and TB?

[速覽]

CB vs sub-block

CU = YUV 的 CB + syntax element

CTB (8×8~64×64) vs MB (16×16)

CTU = YUV  的 CTB + syntax element

UML 類別圖符號

最近又看到一堆 UML 的類別圖, 特別整理了一個符號速查表.
 
 inheritance  B A 繼承 B
 realization AB A 實現 B
 association              B A 關聯 B
 單向 association  B A 關聯 B 
 dependency B A 依賴 B
 註解 A B A 註解 B
 aggregation  B A 彙總 B
 composition  B A 組合 B
 relationship A <<key word>> B access, bind,derive…etc.

[REF]

1. UML類別圖