我讀 «地獄»

丹布朗又出新書了! 昨天到貨的 <Inferno> 終於讀完.

延續過去一貫的風格, 這本書依然環繞著歷史、密碼、符號, 以及人類的生存危機 – 生理上或是心理上的. 至於這次的危機是什麼? 我就不爆料了. 反正全書開始不久就有暗示, 最後峰迴路轉, 不是大家想的那一個的 “那個", 一樣有暗示啦, 讀到最後幾章就能猜得到.

另外, 丹布朗慣用的手法還是好人變壞人, 壞人變好人, 然後又變回來一次的那招. 不過這次的女主角是智商 208 的金髮美女醫師, 我們當然不想她死得太快或是變成壞人囉. 只是作者變變變的梗用太多, 害我連主角的名字都不能寫, 不然立刻就破梗了~~~ 幸好主角還是哈佛大學的教授蘭登, 這個始終一以貫之.

什麼都不能講要講什麼呢? 我想講歷史和地理. 這次的書名叫做地獄, 其實是引用自但丁的神曲, 整個事件都和但丁有關. 話說但丁的神曲描述了地獄、煉獄、和天堂. 但重點大概是在地獄. 地獄共有九層, 像是個漏斗. 撒旦就在最下面. 第一層是給不認識基督的異教徒用的. 不知者也是有罪, 尼安德塔人得在此聽候上帝的審畔. 異端者會受到火刑, 貪食者吃屎等等.

爬過撒旦的尾巴就來到煉獄. 煉獄是分為七層的高山, 靈魂在這邊領到集點卡之後, 每爬上一重山, 就可以消除一種最孽. 犯了七宗罪的人洗去他的罪, 就可以在山頂進入天堂. 而天堂也有九層, 到了最高層的天堂才能見到三位一體的神. 除罪這個動作就是本書解密的梗之一.

另外地獄八層的罪狀和七宗罪非常接近, 就是 貪食、色慾、貪婪、悲嘆、暴怒、懶惰、自負及傲慢. 也就是說自負的人在地獄是有罪的, 但是在煉獄就還 OK, 不列入考核.

七宗罪各自都有一些懲罰的方式, 這也是解謎的梗. 罰錯了方式可不行.

拉丁文 中文
superbia 驕傲
invidia 妒忌
ira 暴怒
accidia 懶惰
avaritia 貪婪
gula 貪食
luxuria 色慾

話說神曲和我們在廟裡看到的 “善書" – 像是天堂遊記、地獄遊記有什麼不同呢? 主要就是文學性. 神曲雖是通俗文學, 但是每三行連韻. WIKI 說: “全詩為三部《地獄篇》《煉獄篇》《天堂篇》,每部33首,最前面增加一首序詩,一共100首。詩句是三行一段,連鎖押韻,各首長短大致相等,每部也基本相等。(地獄4720行;煉獄4755行;天堂4758行),每部都以「群星」(stelle = 英文 star)一詞結束。"  以 star 結束也是一個梗.

除了但丁的神曲, 書中還有許多歷史地理, 特別是與神話相關的歷史. 例如聖露西亞 – 盲人骨頭. 我隨著主角的行程用 Google Map 網游, 也就順便導覽了這些地方. 聖母百花大教堂是綠的、粉紅的、白色的…呃…不看圖還真難明白. 用 GooleMap 大概就能知道作者在講什麼.

佛羅倫斯的聖喬凡尼洗禮堂距離大教堂有多遠? 天堂之門長什麼樣子?

主角在威尼斯大運河西方起點時, 看到的小聖梅西歐教堂有所謂拜占庭的圓頂、古希臘的石柱和山形牆…看圖吧!

有圖之後讀書就更有趣了. 可惜 Google Map 竟然用著用著就在威尼斯當了. 我只好升級成新版的 Google Map. 但用起來一時不習慣. 放 “菊色小人" 在地圖上的介面改了,  幾個地方也就沒有查下去. 看來以後有時間再來網遊伊斯坦堡的蘇非亞大教堂和蓄水池吧!

其實本書還有一個 APP: Dan Brown Inferno", 掃瞄本書的封面就有機會得到簽名書. 不過中文版的封面它好像不認得呢? 我只好放棄了! 其實我倒是希望有實境導覽的 APP, 這樣就可以更有親臨現場的感受. 畢竟 Google 也不容易查到所有建築物的內部裝潢, 那部份都只能靠想像彌補. 但有了這麼好的 APP 或是電子書, 應該會影響電影的版權收入吧! 哈!

耗時六小時的讀書和兩小時的網誌就先告一段落了. 這次義大利犀牛的第四戰輸得更少了, 還打到延長賽. 不過還是四連敗被清盤, 和我預期地差不多. 因為不忍心看轉播, 就專心看書. 希望明年中華職棒還是至少有四隊, 其他不強求.

[ref]

1. 但丁 <<神曲>>

2. WIKI: 神曲

3. 七宗罪

4. 解碼丹布朗

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 A  B A 繼承 B
 realization AB A 實現 B
 association A              B A 關聯 B
 單向 association A  B A 關聯 B 
 dependency A B A 依賴 B
 註解 A B A 註解 B
 aggregation A  B A 彙總 B
 composition A  B A 組合 B
 relationship A <<key word>> B access, bind,derive…etc.

[REF]

1. UML類別圖

 

阿里雲小檔案

阿里雲 (Aliyun) 顧名思義是阿里巴巴的產品, 也是該公司的名稱. 藉著阿里巴巴集團下的淘寶, 支付寶, …等子公司的互相支援下, 阿里雲竟然也在競爭激烈的 OS 市場佔了一席之地.

既然叫做 “雲", 強調的就是雲端技術, 我們可以把阿里雲這家公司想要賣的東西先交代清楚, 然後再來看它會做些什麼?而他的客戶又要做什麼?

對阿里巴巴來說, 他們和其他的雲端公司一樣想要賣網路伺服器, 希望大家把東西存在他們基於飛天開放平台 (Apasara) 的 server 上. 除了硬體也要有軟體, 所以飛天開放平台上也提供: 計算, 存儲, 和資料庫的服務. 就好比 Google 有 gmail, Google doc, Google maps…一樣.

至於大家共通的雲 OS, 則是架在 Linux, Webkit/HTML5/Java Script, OpenGL 和 SQLite 上. 阿里雲號稱他們是基於 Linux, 但 Google 說他們是抄 Android 的 [3], 證據是阿里雲用了 Android 的 run-time lib, framework, 和 tools [4], 也可以跑山寨版的 Google App. 雖然 Google 有反分裂法 (AFA – anti fragmented Agreement), 嚴禁 Android 的客戶自己搞一套服務, 但是阿里雲不但有樣學樣, 竟然還定義了新的指令集! 

根據 [5] 的說法, 我做了個表, 大家變可以知道他們大致上的差異. 據說安兔兔也不能分辨 Android 和 Aliyun. [5] 這篇也講了阿里雲開發的秘辛, 有興趣的人可以參考.

Android 阿里雲
boot loader boot.img 同左
kernel Linux 同左
ROM 目錄結構 app/bin/framework/lib 同左
核心進程 system/bin 同左
 library (.so) system/lib 同左
Framework system/framework 同左
上層 app, launcher system/app 同左
app 副檔名 apk lar
apk 解開之後 class.dex class.lex
虛擬機 (VM) Dalvik 自製 VM

倒底阿里雲好不好用呢?[2] 這篇講得比較詳細, 一共列出 16 點. 其中最大的特色就是阿里雲綁架了桌面, 也限制了阿里雲以外的應用. 如果是阿里雲 market 裡的軟體, 就可以自動備份到雲端. 但是不支援 Google market , 第三方的 app 和 widget 也不提供雲端備份的服務. 基本上就是與 Android 分裂, 另外搞了一個生態圈.

 [ref]

1. 百度百科 – 阿里雲

2. 说说阿里云OS操作系统到底是什么货色

3.  Google 阻止宏碁與阿里雲合作的真實原因

4.  Google+ 文章

5. 纯技术分析阿里云OS和Android之间的关系