Wednesday, December 3, 2014
原則導向與規則導向
我想點出來的是,連勝文是規則導向(rule-centered),而柯文哲是原則導向(principle-centered)。比如說講到廉潔,兩邊都有一個故事,連勝文這邊是說他在悠遊卡公司的時候,公司在敦化北路跟民生東路口附近,而他丈母娘的紅豆食府就在附近,但他只要是公司出錢的聚餐,為了避嫌都不會去紅豆食府,乍聽之下,似乎很清廉自持,但後面一點他說了,他悠遊卡董事長上任第一天,有人給了他一本廉政的手冊吧,上面就有提到一個小故事,是說類似的事情,說公司的聚餐不能去認識的人的餐廳裡面等等,也就是說他這個清廉自持的行為是因為有人寫了一個「規則」在哪裡,整場專訪,連勝文也相當強調「依法行事」這件事情,這就是 rule-centered 的行事風格。而柯文哲先生對於廉潔,也有個故事,但是他是講到他在台大人際關係不好的時候提到的,他是說台大醫院開會訂便當的時候,一向是打電話給廠商(比如說抗生素廠商等等)送便當進來,而柯文哲當了主管的第一天就要求屬下不得這樣做,開會一律自己買便當,所以才有 MG149 的私帳(因為這些都得自己出錢,但又需要管理,其實就是類似班費)。看得出來,柯文哲是在群體壓力下,堅守一個原則,而不是依照既有規則來行事。另外,講到說實話這件事,他非常堅持誠實這個原則,所以當他發現他講真話(失言風波),媒體很反彈,他說他回去苦惱了很多天,最後想說這跟道德也沒什麼關係,只是尊重聽這些話的人,所以他就做了修正。像這一類行事方法,就是原則導向,亦即心中有一些原則,是大方向,面對每天不同的事件發生的時候,依據這些心中的原則來行事,而且會有優先順序的。
規則導向的行事風格不會出什麼大錯,行事很安全,但有時候會不通情理,比方說有個丈夫因為妻子羊水破了,要趕緊到醫院生產,於是一路超速,警察把他攔下來發現他是因為妻子要生產才超速,規則導向的人這時候就會堅持說你犯了法,必須要開單,因為要依法行事,然後依法也沒規定警察必須要護送孕婦,於是就不理他。這就是規則導向的行事風格。原則導向的行事風格的警察,在攔下來發現超速的原因之後,會衡量各種原則,發現生命當然是優先的,於是罰單也不開,而且還護送這台車一路到醫院。事後來看,後面那個警察做的事情對嗎?的確有人超速而不開單,那麼他是不是包庇違法的事情發生呢?如果有人不問當時發生的狀況與當事人應對的方式,只挑出部份的違法證據來指控對方違法,就落入了規則導向的方式。
原則導向也是兩個當中,能夠開創新局的方式。如果面對一個全新的領域或全新的世界,既有的規則都不能應用,一個規則導向的行事風格就會陷入混亂當中,因為完全沒有規則可循,或是隨便引用相近的陳舊規則來應用在全新的事情上面,這是不是很熟悉?這就是近十幾年來,陳舊的法規面對全新的世界的時候的混亂。以原則導向來說,就會像美國憲法這樣,先條列出行事的原則,而當有任何新的事件發生,就回去檢視這些原則,仔細考量,最後選擇這個新事件要怎麼處理,如此才能夠面對瞬息萬變的世界,而通常這些原則就是一個團體、個人要堅守的價值。
原則導向有個很重要的人一定要提,那就是富蘭克林(Benjamin Franklin, 1706--1790)在他的自傳提過他隨身帶了一本小冊子,稱之為 "The Little Book",上面列了十三條原則,每週選定一個原則來強化,但每天晚上都會針對這十三條原則檢討自己當天的行事是否遵循了這些原則。沒有遵循的地方檢討原因是什麼,但不過分責備自己。注重長期來說,是否有進步。富蘭克林後來說了 "Tho’ I never arrived at the perfection I had been so ambitious of obtaining, but fell far short of it, yet I was, by the endeavour, a better and a happier man than I otherwise should have been if I had not attempted it. " 富蘭克林的這句話是說,他從未達到他原來所想要達到的完全,但是透過熱切的追尋,他變成一個比未追尋完全之前更好更快樂的人。只有這樣子才能夠進步。在 Stephen Covey 的書[3] 「與成功有約」裡面則是把富蘭克林的方法進一步加一些改變並且仔細的闡述,對原則導向有興趣的人可以參考一下。
規則導向我想到的代表人物是馬英九總統,看他的行事風格你就會知道什麼叫做規則導向,他最常把「依法行事」掛在嘴邊,對於一些大家都知道要為大原則放棄追小錯的時候,他只會專注在那個錯誤之上。所以規則導向就是在任何事情發生的時候,一定是檢討有沒有違反規則,並且對違反規則耿耿於懷。因為犯錯就是犯錯,沒有什麼逐漸改善讓犯錯率變少這件事。這是因為規則導向常常會有非常多的規則,而且是針對非常明確的事情做規範,比方說全勤獎金就是個很規則導向的事情,全勤的定義是你這個月每天都到,如果你有一天因為生病而沒到,就是沒有全勤獎金,不論你缺席的理由是什麼。但是原則導向就會去思考,全勤的意義是什麼?然後可能思考出全勤的意義在於你對於公司的貢獻,所以訂定了工作進度,只要你每個月達到工作進度就獎勵,而你中間是否因病缺席,就不在考量範圍內。
寫了這麼多,簡單總結一下,原則導向就是望向未來,而規則導向就是依循過去。 我不是在講哪一個個人怎麼樣,而是哪一種行事方法能夠帶領個人、公司、社會,甚至國家往未來瞬息萬變的挑戰,其實很清楚。
[1] 柯文哲專訪 柯文哲專訪
[2] 連勝文專訪 連勝文專訪
[3] Stephen Covey, "The 7 Habits of Highly Effective People" (中文翻譯:與成功有約)
Thursday, August 7, 2014
LaTeX 字型安裝筆記: Adobe Garamond Pro 字型
LaTeX 字型安裝筆記: Adobe Garamond Pro 字型
上一篇文章筆者提到了 Garamond 字型有非常多個供應者, 其中一個就是 Adobe Garamond Pro 字型, 這是 Adobe 公司出品的商業字型, 在 LaTeX 上同樣也是由 mathdesign
這個套件來支援。
筆者先假設你購買或從他處取得 Adobe Garamond Pro 的以下檔案:
- AGaramondPro-Regular.otf
- AGaramondPro-Italic.otf
- AGaramondPro-Semibold.otf
- AGaramondPro-SemiboldItalic.otf
請把以上這些檔案複製到 $TEXMF/fonts/opentype/garamond/Adobe Garamond Pro
的字型目錄裡面, 在筆者的 Mac 上我把他們複製到 ~/Library/texmf/fonts/opentype/garamond/Adobe Garamond Pro
裡, 然後執行 sudo texhash
更新系統路徑。
使用的方法是:
\usepackage[adobe-garamond]{mathdesign}
然後你就可以在 LaTeX 裡面使用 Adobe Garamond Pro 這一套商業字型了, 有任何其他的使用細節, 可以在 CTAN 上搜尋 mathdesign 套件 的說明檔案。
P.S.: 這樣安裝的 Open Type 字型只可以使用在 PDFLaTeX 上, LaTeX->DVIPS 這個路徑需要其他的安裝方法。
Wednesday, August 6, 2014
LaTeX 字型安裝筆記: URW Garamond 字型
LaTeX 字型安裝筆記: URW Garamond 字型
Garamond 是一種描邊字型家族, 泛指由法國的鉛字鑄造師 Claude Garamond~(c. 1480–1561) 設計的字型或後人衍生的字型。許多與 Garamond 有關聯的字型則出自於另一位鉛字鑄造師 Jean Jannon。Garamond 同時也是印刷的時候, 最省墨水或碳粉的字型。1
Garamond 字型有非常多提供者, 有基於 Garamond 設計而衍生的: Adobe Garamond, Garamond Premier, Sabon, EB Garamond, URW++ Garamond No. 8 或是基於 Jannon 而衍生的: ITC Garamond, Garmond 3 等字型, 其中我們今天要講的是 URW++ 所製作的免費 Garamond 字型, 這個字型被內建在 Ghostscript 程式套件裡面, 並且被 TeX 社群引入到 LaTeX 字型中, 其格式是 PostScript Type1 格式。要使用這個字型, 你必須先安裝
mathdesign
這個套件。使用方法如下:
\usepackage[urw-garamond]{mathdesign} \usepackage[T1]{fontenc}
如果你無法使用, 別急, 很可能是你的 TeX 系統沒有附上這套字型, 雖然這套允許非商業用途免費使用, 但 TeX 不一定會附上, 你可以到 CTAN Garamond 網頁 下載所有的 afm 以及 pfb 檔, 並且放置在正確的路徑上, 筆者把
*.afm
放到 ~/Library/texmf/fonts/afm/urw/garamond
裡, 並且把 *.pfb
放到 ~/Library/texmf/fonts/type1/urw/garamond
裡面。筆者的電腦是 Mac, 其他系統請參考相關 TeX 系統的說明。放完之後要更新路徑, 讓 TeX 系統能夠使用這些字型, 只要在終端機輸入 texhash
即可。URW++ Garamond 是一套附有數學符號的描邊字型, 除了有最省墨水或碳粉之外, 也被認為是可讀性很高的一個字型, 如果你已經厭倦 Times Roman 字型, 不妨可以來試試這一套字型。
Friday, August 1, 2014
在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 =\epsilon= (\epsilon) 與 =\ell= (\ell) 的問題解法
\epsilon
(ε) 與 \ell
(ℓ) 的問題解法在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 \epsilon
(ε) 與 \ell
(ℓ) 的問題解法
1 前言
Minion Pro1 是一個 Adobe 出品的 Serif 字型, 內建在 Adobe Reader2 與 Adobe Acrobat 裡面, 是一套高品質且漂亮的字型, Myriad Pro3 則是同樣內建在軟體內的 Sans Serif 字型。有興趣的讀者可以先到 footnotes 上去找兩套字型的範例。兩套字型的格式都是 Open Type, 而且免費贈送, 如果我們想要在自己的 LaTeX 檔案裡面使用, 要怎麼安裝呢?以下這篇文章就會介紹安裝過程以及這兩套字型相關的問題與解法,所有範例都是以 MacOSX 為主, 其他系統請自行找尋相關資源。
2 準備檔案
- TeX 系統
你必須先安裝好 TeX/LaTeX 系統, Windows 的話一般是 MikTeX 比較受歡迎, 而 Mac 則是 MacTeX, 兩者都是基於 TeXLive 衍生出來的, 如果是 Linux 使用者的話, 就直接安裝 TeXLive 即可。
- MnSymbol 套件
安裝完 TeX/LaTeX 系統之後, 用系統附的套件管理員安裝 MnSymbol 這個套件。MnSymbol 是搭配 MinionPro 使用的數學符號字型, 相關的符號可以參考 4 裡面的說明檔。
- LCDF typetools
一般來說安裝完 TeX/LaTeX 系統後就會有 LCDF typetools 了, 你可以在終端機下命令檢查:
Aquila:Font albert$ otfinfo --version
otfinfo (LCDF typetools) 2.100
Copyright (C) 2003-2013 Eddie Kohler
This is free software; see the source for copying conditions.
There is NO warranty, not even for merchantability or fitness for a
particular purpose.
如果沒有的話, 請用套件管理員或請到 LCDF Type Software 下載安裝。
- CTAN 上的 MinionPro 套件
如果 TeX/LaTeX 套件管理員沒有列 MinionPro, 那麼就請你到 CTAN 下載以下檔案:
- http://mirrors.ctan.org/fonts/minionpro/enc-2.000.zip
- http://mirrors.ctan.org/fonts/minionpro/metrics-base.zip
- http://mirrors.ctan.org/fonts/minionpro/metrics-full.zip
- http://mirrors.ctan.org/fonts/minionpro/metrics-opticals.zip
- http://mirrors.ctan.org/fonts/minionpro/scripts.zip
- Minion Pro 與 Myriad Pro 字型檔
在你安裝完 Adobe Reader 或 Acrobat 之後, 你就會在 /Applications 有一個 "Adobe Reader.app" 而 Minion Pro 與 Myriad Pro 字型檔會放在 /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/
裡面
Aquila:~ albert$ cd /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/
Aquila:Font albert$ ls
AdobePiStd.otf MinionPro-BoldIt.otf MyriadPro-Regular.otf ZY______.MMM
CourierStd-Bold.otf MinionPro-It.otf SY______.PFB ZY______.PFB
CourierStd-BoldOblique.otf MinionPro-Regular.otf SY______.PFM ZY______.PFM
CourierStd-Oblique.otf MyriadPro-Bold.otf ZX______.MMM
CourierStd.otf MyriadPro-BoldIt.otf ZX______.PFB
MinionPro-Bold.otf MyriadPro-It.otf ZX______.PFM
如果你安裝的是 Acrobat, 那麼把 /Applications 下的 Adobe Reader.app 取代成 Acrobat.app 即可。先把這個路徑記起來, 等一下會用到。
3 安裝
檔案準備完之後, 就要開始安裝過程了, 筆者先認定你已經會操作終端機, 如果不知道的話, 請在網路上搜尋終端機的使用方式, 請先開啟終端機(or Terminal.app)。
先切換使用者目錄到 scripts.zip 解壓縮的地方, 一般會在 ~/Downloads/scripts 裡面:
Aquila:~ albert$ cd ~/Downloads/scripts/
Aquila:scripts albert$ cp /Applications/Adobe\ Reader.app/Contents/Resources/Resource/Font/*.otf ./otf
Aquila:scripts albert$ ./convert.sh
Creating PostScript fonts ...
AdobePiStd: has no 'j' glyph to make dotless
cfftot1: glyph 'sterling.oldstyle': While processing otf/MinionPro-Bold.otf:
cfftot1: glyph 'sterling.oldstyle': warning: complex flex hint replaced with curves
cfftot1: (This Type 2 format font contains flex hints prohibited by Type 1.
cfftot1: I've safely replaced them with ordinary curves.)
MinionPro-Bold: already has a dotlessj glyph at 'uni0237'
MinionPro-BoldIt: already has a dotlessj glyph at 'uni0237'
cfftot1: glyph 'colonmonetary.oldstyle': While processing otf/MinionPro-It.otf:
cfftot1: glyph 'colonmonetary.oldstyle': warning: complex flex hint replaced with curves
cfftot1: (This Type 2 format font contains flex hints prohibited by Type 1.
cfftot1: I've safely replaced them with ordinary curves.)
MinionPro-It: already has a dotlessj glyph at 'uni0237'
MinionPro-Regular: already has a dotlessj glyph at 'uni0237'
Aquila:scripts albert$ mkdir -p ~/Library/texmf/fonts/type1/adobe/MinionPro
Aquila:scripts albert$ cp ./pfb/*.pfb ~/Library/texmf/fonts/type1/adobe/MinionPro
然後解壓縮字型相關檔案
Aquila:scripts albert$ cd ~/Library/texmf
Aquila:scripts albert$ unzip enc-2.000.zip
Aquila:scripts albert$ unzip metrics-base.zip
Aquila:scripts albert$ unzip metrics-full.zip
更新字型地圖,
Aquila:scripts albert$ updmap
執行的結果應該會列出 ~/Librar/texmf/fonts/map/dvips/MinionPro/MinionPro.map 以及 ~/Librar/texmf/fonts/map/dvips/MyriadPro/MyriadPro.map
找到之後, 預設是 disable 的, 你要下命令啟動他們:
Aquila:scripts albert$ updmap --enable Map=MinionPro.map
Aquila:scripts albert$ updmap --enable Map=MyriadPro.map
到這邊如果安裝過程順利沒有什麼錯誤的話, 這兩套字型就算是安裝完成了。
4 使用
想要在你的 LaTeX 檔案裡面使用 MinionPro 字型, 只要在 preamble 寫下:
\usepackage{MinionPro} % 使用 Minion Pro 字型
\usepackage{MnSymbol} % 使用搭配 MnSymbol 的數學字型
另外, 預設的 text figure 一般人可能不太習慣, 可以選擇 lining figure 如下:
\usepackage[lf]{MinionPro} % 使用 Minion Pro 字型, lining figure
兩者的差異如圖所示:
其他更詳細的使用方法, 請參考 CTAN 連結上面的 MinionPro.pdf 檔案。安裝過程就介紹到這裡了。
5 \epsilon
變成方塊的問題
有數種解決方法, 不過最簡單的是用 \varepsilon
取代, 或是在 preamble 設定
\renewcommand{\epsilon}{\varepsilon}
6 \ell
Adobe Reader 9 之後 \ell
被更改編碼位置, 但是 enc-2.0.0 未反映這個更新, 要修正這個問題, 就請修改 base-MinionPro-ab.enc 這個檔案, 他應該在 ~/Library/texmf/fonts/enc/dvips/MinionPro 裡面, 打開檔案後, 把 "afii61289" 取代成 "uni2113" 然後存檔即可。
7 結語
TeX/LaTeX 是一個高品質的排版系統, 桌上型排版發展了這麼多年, 一直還沒有任何其他排版軟體能夠真正的取代它的地位, 雖然學習曲線比較陡峭, 但依然值得我們花精神學習它。LaTeX 的字型安裝一直是令人頭痛的問題, 這篇文章簡單的介紹如何安裝 Minion Pro 與 Myriad Pro 兩套字型, 讓使用者在 LaTeX 使用它們, 希望能夠減緩一些安裝字型時頭痛的程度, 讓各位更能享受 LaTeX 的排版品質。
Monday, March 3, 2014
漫談分貝(dB) 這一堆玩意兒
今天是 3 月 3 日, 恰好是發明電話的貝爾的生日, 所以今天我們來談以貝爾的姓氏命名的單位, Bel 以及 decibel(分貝或 dB)。剛開始接觸數位訊號處理或是通訊領域, 最常令人困惑的就是 dB 這個玩意兒, 它既不是一個單位, 也不怎麼直覺, 接下來就讓我們來看看這玩意兒吧。
分貝(dB, or decibel) 當初是拿來描述量測的電話線訊號衰減量, 在 1928 年貝爾系統公司(貝爾電報電話公司的相關企業)把原本使用的 Transmission Unit(TU) 改名為 decibel, 並且增加 Bel(1 Bel = 10 decibel), 用來紀念發明電話的貝爾(Alexander Graham Bell, March 3, 1847 – August 2, 1922),1 文章發布的今天剛好是他的生日。
分貝是拿來描述衰減量的, 只是一個相對單位而已, 就像一般講的數量級一樣, 一個數量級代表的是十倍, 而 1 Bel 就是 10 dB, 是由以 10 為基底的對數函數產生:
\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}要先記住上述衰減量是拿來描述功率衰減的, 我們也可以用 dB 描述振幅的衰減量, 而初學者很容易搞混計算功率以及振幅衰減的分貝公式。
功率:
\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} \end{equation}振幅(如電壓、電流、聲壓):
\begin{equation} L_{dB} = 20~\log_{10} \frac{A_1}{A_2} \end{equation}只要先記得分貝都是計算功率的公式, 再利用電路的基本公式: \(P=IV=\frac{V^2}{R}\), P 為功率, I 為電流, V 為電壓, R 為電阻, 那麼:
\begin{equation} L_{dB} = 10~\log_{10} \frac{P_1}{P_2} = 10~\log_{10} \frac{V_1^2}{V_2^2} = 20~\log_{10} \frac{V_1}{V_2} \end{equation}而大部分功率都是振幅的平方倍, 所以都可以得到上述的式子, 因此振幅計算公式前面的常數是 20。
當倍數轉換成分貝讓乘法轉換成加法, 除法轉換成減法, 使得運算更為簡單, 其數值也不容易超過能夠表示的範圍。例如接收機的情況, 從發射機一路到接收機的各級增益, 按照順序列表:
- 發射機 \(P_{TX} = 1W = 10\log_{10} \frac{1W}{1mW} = 10\log_{10} 1000 = 30 dBm\)
- 發射天線增益 \(G_{TXANT} = 10 dBi\), 或 10 倍
- 空氣中衰減 \(ATT_{channel} = -60 dB\), 或 1/1000000 倍
- 接收機天線增益 \(G_{RXANT} = 10 dBi\), 或 10 倍
- 接收機 LNA 增益 \(G_{RX} = 20 dB\), 或 10 倍
計算各級增益, 以 dB 來計算,只要算
\begin{equation} RSSI_{dB} = P_{TX} + G_{TXANT} + ATT_{channel} + G_{RXANT} + G_{RX} = 30 + 10 - 60 + 10 + 20 = 10 dBm \end{equation}而用倍數來計算則會是這樣:
\begin{equation} RSSI = 1 * 10 / 1000000 * 10 * 10 = 0.001 \end{equation}可以看出用倍數算會出現動態範圍比較大的整數或小數, 而 dB 值只要加加減減就出來了, 這在浮點運算的時候看不出好處, 但在定點運算上可以看出來上述的例子, dB 的計算只要給有號整數部分 8 個位元即可表示, 而線性尺度(linear scale, 也就是上述所稱的倍數) 的計算則會做到超過 20 位元的除法。
除了運算上會變得動態範圍變小以外, dB 公式中的對數函數也有將比較小的數值變化放大並將比較大的數值變化縮小的功用。
Figure 1: 線性尺度
Figure 2: dB 尺度
可以看得出來 320kHz 以下的變化原本在線性尺度看不太出來, 但在 dB 尺度看出來上下變化範圍有 10 dB 的大小, 這對訊號來說已經算是不小的影響。而線性尺度看起來差異很大(一半)的 400kHz 到 900kHz 的範圍, 在 dB 尺度上只有 4 dB 左右, 320kHz 變化 10 dB 在這個例子中, 因為那不是我們要的訊號, 所以影響不大, 但若發生在我們想要的頻譜上, 線性尺度可能就會看不太出來, 這個是 dB 尺度的優點。
以上就是對於 dB 簡單的介紹, 那麼我們常常看到 dB 後面還加上一些字母, 那是什麼意思呢?我們來看一些常用的 dB 家族。
分貝後面如果加上了其他的字母, 代表分母的參考量, 就會從相對值變成絕對值。
- dBm 代表分母是 1mW, 所以 \(dBm = 10~\log_{10} \frac{P}{1mW}\)
- dBW 代表分母是 1W, 所以 \(dBW = 10~\log_{10} \frac{P}{1W}\)
如果是分貝後面加上其他字母, 但是該字母被括號刮起來, 是代表訊號的種類。
- dB(A) 代表聲壓, 是一個絕對單位, 參考訊號位準是 \(20~\mu~Pa\),2 是人耳所能聽到的下限, 又因為聲音是振幅, 所以計算公式為:
聲音用 dB 來表示是因為耳朵對於壓力變化大小是對數級的, 至於頻率變化也有類似的關係, 因此對於噪音計算定義了 octave band filter, 每一個 octave band 的中心頻率是下一個 band 的 2 倍或 1/2。3
dBi 是用來描述天線增益, 定義是最大的波束相對於理想均勻球體輻射樣式(isotropic) 的增益。
dBm/Hz 則是拿來描述功率密度(power spectral density), 意思就是每 1 Hz 所含的功率, 如果你有功率密度 -30 dBm/Hz, 在 10 MHz 寬度上都是平坦的, 其他地方的數值都小到可以忽略, 那麼總發射功率就是 \(-30 + 10 \log_{10} {10 \times 10^6} = 40 dBm = 10W\)
我們描述 SNR(訊雜比) 的時候也常常用 dB 來描述, 大部分的接收機, 比如說 Wifi, Bluetooth, LTE, WCDMA 等等都會顯示 SNRdB, 而筆者常常看到有人引用這個 SNR 值的時候, 忘記加上 dB, 這樣會造成非常大的誤解與巨大的差異, 舉例來說, 如果 SNR 是 60 dB, 而引用的時候說 SNR 是 60, 那麼這個意思就是 \(\frac{P_{signal}}{P_{noise}} = 60\) 了, 而 \(60~dB = 10^{\frac{60}{10}} = 1000000\), 差距有 \(\frac{1000000}{60} = 16666.7\), 有上萬倍的差異啊!筆者知道分貝對初學者來說, 是個不容易搞懂的數量, 因此寫了這篇文章, 希望大家在接觸訊號與通訊領域的時候, 看到 dB4 能夠不再那麼陌生。
Tuesday, February 18, 2014
談談 ARM Cortex-M4F 上的 DSP 功能
Table of Contents
1 談談 ARM Cortex-M4F 上的 DSP 功能
1 前言
從 ARM2 在 1986 年問世以來, ARM 的處理器一向以省電性聞名, 之後到了智慧型手持裝置的時代, 省電性更是非常迫切的需求, 到了 2005 年, 有 98% 的手機上面至少有一顆 ARM 的處理器。1 專精於數位訊號處理的工程師, 除了傳統的數位訊號處理器以外, 勢必要了解一下這樣的趨勢, 以及如何在自己的專案中評估使用 ARM 處理器的可能性, 本文將會針對與中低階 DSP 較為類似的 ARM Cortex-M4F 上的 DSP 功能來討論。
2 ARM Cortex-M4F 功能簡介
ARM Cortex-M4F 是 ARM Cortex-M 系列的處理器裡面功能最為強大的一個, 而 Cortex-M 系列的 M 是指 microcontroller, 下表列舉了部分的 Cortex-M 系列處理器的比較, 可以看出 Cortex-M4F 在指令集上有硬體乘法、硬體除法、飽和運算、數位訊號處理延伸指令以及浮點運算。
ARM Cortex-M 系列指令集支援2
ARM Cortex-M | Thumb | Thumb-2 | 硬體乘法器 | 硬體除法器 | 飽和運算 | DSP 延伸功能 | 浮點 | ARM 架構 | 核心架構 |
---|---|---|---|---|---|---|---|---|---|
Cortex-M3 | 完整 | 完整 | 單一時脈 | 有 | 有 | 無 | 無 | ARMv7-M | Harvard |
Cortex-M4 | 完整 | 完整 | 單一時脈 | 有 | 有 | 有 | 選項 | ARMv7E-M | Harvard |
另外, Cortex-M4F 還有以下特點是數位訊號處理器程式設計師會注意的:
- 沒有快取記憶體
- 沒有記憶體管理單元(MMU)
- 記憶體保護單元(MPU) 是選項功能
- 中斷處理延遲最長 12 個時脈
在擁有 DSP 能力的處理器中, 有幾個分類:
- 數位訊號處理器(Digital Signal Processor)
- 數位訊號控制器(Digital Signal Controller)
第一種就是一般印象中的數位訊號處理器, 其特點就是架構完全針對數位訊號處理而優化, 是真正能夠持續的以單一時脈執行乘積累加運算, 亦即乘積累加所需的運算元會在下一個時脈就已經載入並執行運算, 而不用等待運算元從記憶體載入的時間, 發揮極致的運算能力, 但是設計複雜度比較高, 一般來說省電性不如微處理器或微控制器。這種有 TI TMS320C67x 定點與浮點 DSP 系列與很早期的 Motorola(現為 Freescale) DSP56300(這是 Steve Jobs 出走 Apple 時創立的 NeXT 公司在他們的工作站使用的 DSP56001 的下一代產品線, 是特殊的 24-bit DSP)。大部分的 DSP 只支援定點運算, 因為同樣的面積與功耗, 定點運算能夠提供更高的運算能力, 而且以訊號處理的應用而言, 不需要浮點數這麼高的動態範圍。當然, 浮點 DSP 還是有其優勢, 尤其是在一些必須縮短開發時間的應用上, 浮點數能力使得程式設計師不需要耗費太多精神與時間處理定點數運算。
第二種就是把微控制器整合數位訊號處理能力而成, 以傳統的微控制器為主, 擁有豐富的周邊支援與輸出入腳位。ARM Cortex-M4F 屬於這一個分類, 並且因為 ARM 架構被廣泛的支援, 使得 ARM Cortex-M4F 擁有豐富的工具可以應用。以 STMicroelectronics 公司的 STM32F 系列來說, 其 10ku 報價在 2 至 10 美元之間, 往下與 16-bit MCU 重疊, 往上與入門級 DSP 重疊。
3 DSP 運算的核心: 乘積累加(Multiply-and-Accumulate)
我們常常看到支援數位訊號處理能力的處理器都會強調其乘積累加(MAC, or Multiply-and-ACcumulate) 的能力, 這是因為在數位訊號處理演算法上, 大量的使用 MAC 運算。
不管是有限響應濾波器:
\begin{equation} y[n] = \sum_{k=0}^{N-1} h[k]x[n-k] \end{equation}或是無限響應濾波器:
\begin{equation} y[n] = b_0 x[n] + b_1 x[n-1] + b_2 x[n-2] + a_1 y[n-1] + a_2 y[n-2] \end{equation}還是快速傅利葉轉換中很重要的 butterfly 運算:
\begin{eqnarray} Y[k_1] & = & X[k_1] + X[k_2] \\ Y[k_2] & = & (X[k_1] - X[k_2])e^{-j\omega} \end{eqnarray}這些都非常仰賴乘積累加的運算。
ARM Cortex-M4F 與乘法或乘積累加有關的指令集如下表2:
運算 | 指令意義 | 指令列表 |
---|---|---|
16 * 16 = 32 | Signed Multiply (SMUL) | SMULBB, SMULBT, SMULTB, SMULTT |
16 * 16 + 32 = 32 | Signed Multiply and Accumulate (SMLA) | SMLABB, SMLABT, SMLATB, SMLATT |
16 * 16 + 64 = 64 | 16-bit Signed Multiply with 64-bit Accumulate (SMLAL) | SMLALBB, SMLALBT, SMLALTB, SLMALTT |
16 * 32 = 32 | 16-bit by 32-bit signed multiply returning 32 MSB, i.e. word (SMULW) | SMULWB, SMULWT |
(16*32) + 32 = 32 | Q setting 16-bit by 32-bit signed multiply with 32-bit accumulate (SMLAW) | SMLAWB, SMLAWT |
(16*16) + (16*16) = 32 | Q setting sum of dual 16-bit signed multiply (SMU-AD) | SMUAD, SMUADX |
(16*16) - (16*16) = 32 | Dual 16-bit signed multiply returning difference (SMU-SD) | SMUSD, SMUSDX |
(16*16) + (16*16) + 32 = 32 | Q setting dual 16-bit signed multiply with single 32-bit accumulator (SMLAD) | SMLAD, SMLADX |
(16*16) - (16*16) + 32 = 32 | Q setting dual 16-bit signed multiply subtract with 32-bit accumulate (SMLSD) | SMLSD, SMLSDX |
(16*16) + (16*16) + 64 = 64 | Dual 16-bit signed multiply with single 64-bit accumulator (SMLALD) | SMLALD, SMLALDX |
(16*16) - (16*16) + 64 = 64 | Q setting dual 16-bit signed multiply subtract with 64-bit accumulate (SMLSLD) | SMLSLD, SMLSLDX |
32 * 32 = 32 | Multiply | MUL |
32 + (32 * 32) = 32 | Multiply accumulate | MLA |
32 - (32 * 32) = 32 | Multiply subtract | MLS |
32 * 32 = 64 | Long signed/unsigned multiply | SMULL, UMULL |
(32 * 32) + 64 = 64 | Long signed/unsgiend accumulate | SMLAL, UMLAL |
(32 * 32) + 32 + 32 = 64 | 32-bit unsigned multiply with double 32-bit accumulation yielding 64-bit result | UMAAL |
32 + (32 * 32) = 32 MSB | 32-bit multiply with 32-most-significant-bit accumulate | SMMLA, SMMLAR |
32 - (32 * 32) = 32 MSB | 32-bit multiply with 32-most-significant-bit subtract | SMMLS, SMMLSR |
(32 * 32) = 32 MSB | 32-bit multiply returning 32-most-significant-bits | SMMUL, SMMULR |
以上都是定點運算3, 並且每一個指令都能夠在一個時脈執行完畢, 或許你會問:「我只想寫 C 語言, 而且已經有函式庫, 為什麼還需要了解指令集呢?」如果你不碰數位訊號處理應用, 或許可以不用了解這一顆處理器的指令集, 但就像作業系統的程式設計師必須要了解處理器關於作業系統的指令集一樣, 數位訊號處理工程師必須在了解所有 DSP 指令集後, 想盡辦法像國稅局一樣榨乾這顆處理器, 一滴都不能剩。尤其是函式庫提供的定點運算都只有 Q31 與 Q15 的選擇, 如果你有其他特殊的需求, 就得自己寫數位訊號處理程式碼。在 C 語言的優化過程中, 使用指令集的 intrisincs 是不可避免的。
ARM Cortex-M4F 也有符合 IEEE-754 規範的浮點運算單元, 而單精確浮點數在訊號處理演算法上扮演很重要的角色, 下表列舉了單精確浮點數的運算與時脈數:
單精度浮點運算 | 指令 | 執行時脈 |
---|---|---|
加/減 | VADD.F32, VSUB.F32 | 1 |
乘法 | VMUL.F32 | 3 |
乘積累加 | VMLA.F32, VMLS.F32, VNMLA.F32, VNMLS.F32 | 3 |
Fused MAC | VFMA.F32, VFMS.F32, VFNMA.F32, VFNMS.F32 | 3 |
平方根 | VSQRT.F32 | 14 |
除法 | VDIV.F32 | 14 |
可以看出浮點數的乘法比較花時間, ARM Cortex-M4F 有提供 fused MAC 指令以增加精確度。
接下來, 我們來看實際上拿 ARM Cortex-M4F 寫數位訊號處理程式的時候的效能, 以下是一般標準的 FIR 濾波器的程式碼:
void fir(q31_t *in, q31_t *out, q31_t *coeffs, int *state, int numTaps, int blkSize) { int sample; int k; q63_t sum; /* Q2.62 in 64-bit acccumulator */ int idx = *state; for (sample=0; sample<blkSize; sample++) { state[idx++] = in[sample]; sum = 0; for (k = 0; k < numTaps; k++) { sum += (q63_t) coeffs[k] * state[idx]; /* 1. Fetch coefficient and sample. 2. Perform MAC */ idx--; /* Pointer update for circular addressing */ if (idx < 0) { idx = numTaps - 1; } } out[sample] = (q31_t) (sum >> 31u); // Convert Q2.62 to Q1.31 } *state = idx; }
參考更早之前的 FIR 濾波器運算式:4
\begin{equation} y[n] = \sum_{k=0}^{N-1} h[k]x[n-k] \end{equation}h[k] 就是 coeffs[k], x[n-k] 就是 state[idx], numTaps 就是 N, out[sample] 則是 y[n].
在最內側的迴圈中包含了:
- 載入係數與輸入取樣
- 執行乘積累加運算
- 循環定址的指標更新
在現代 DSP5 中, 上述運算可以在一個或兩個時脈內執行完畢, 如:
do x0,FirLoop mac x1,y1,a x:(r0)+,x1 y:(r4)+,y1 FirLoop
這個迴圈指令是 zero overhead loop, 而且只需一個時脈指令就能完成上述三項最內側迴圈需要完成的事項。這是數位訊號處理器的能力, 而且也需要使用組合語言來優化, 那我們來看 ARM Cortex-M4F 用 C 語言能夠達到的速度:
動作 | 時脈數 |
---|---|
載入 coeffs[k] | 2 |
載入 state[idx] | 1 |
乘積累加 | 1 |
idx-- | 1 |
循環定址 | 4 |
迴圈 overhead | 3 |
總共 | 12 |
從上述表格中可以看出, 即便 ARM Cortex-M4F 這類數位訊號控制器擁有一個時脈就可以完成的乘積累加指令, 加上其他額外的執行成本, 就增加到 12 個時脈才能完成一個乘積累加。有一些 C 語言優化的方式:
- Circular addressing alternatives
- Loop unrolling
- Caching of intermediate variables
- Extensive use of SIMD and intrinsincs(還是用上指令集)
如果用上這些, 並且輸入以及係數是 16-bit 的情況下, 是可以達到平均每個乘積累加 1.625 個時脈的程度。6如果需要的精確度是 32-bit 的情況下, 可能會需要更多時脈, 但已經與數位訊號處理器差距不算遠了, 當然若與同樣擁有 SIMD 能力的數位訊號處理器並且優化相比, 還是差上一大截, 但是搭配 ARM 廣泛的周邊與軟體資源, 這樣的效能已經很吸引人。
在數位訊號處理程式上, ARM 提供了 CMSIS(Cortex Microcontroller Software Interface Standard) DSP 函式庫, 在實際開發時只需要呼叫這些函數即可, 但要善用這個函式庫, 還是需要對於數位訊號處理基本概念有認識才行。
另外, 在使用 ARM Cortex-M4F 的累加器的時候, 需要注意的是, 累加器不會自動作飽和動作, 因此做定點運算的時候, 必需自行預留累加的空間, 或是先將數值預先縮小以避免溢位。
4 結語
從 ARM7 問世開始, ARM 這間公司展現的企圖就是除了 32-bit microprocessor 以外, 還要開始蠶食 8-bit/16-bit MCU 的市場, 經過了一陣子的努力之後, 繼續推出了 ARM Cortex-M 系列展現強烈的企圖心, 如今採用的公司漸漸增多, 侵蝕了部分 16-bit MCU 的市場, MCU 程式設計師必須要看清這個趨勢, 學習 ARM 系列架構來接受這個潮流變化。Cortex-M 系列最高接的 Cortex-M4F 提供了數位訊號處理能力, 成為數位訊號控制器, 在省電性主導的地方, 與 16-bit DSP 相比互有優劣, 但 Cortex-M4F 提供了 32-bit 浮點運算, 讓開發時間能夠縮短, 千萬不可小看 ARM 在數位訊號控制器上的未來性。本文只討論了 ARM Cortex-M4F 的 DSP 能力以及在新的 DSP 專案中使用 ARM Cortex-M4F 的可能性, 筆者將在後續的文章中陸陸續續介紹如何使用 Cortex-M4F 來做實際的數位訊號處理應用。
Footnotes:
Tom Krazit, ARMed for the living room, http://news.cnet.com/ARMed-for-the-living-room/2100-1006_3-6056729.html
ARM® Cortex™-M4 Processor Technical Reference Manual Revision r0p1, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439d/index.html
有關於定點數 Q format 可以參考我之前寫的「定點數表示法」, http://alberthuang314.blogspot.tw/2012/08/blog-post.html
有關於 FIR 有限響應濾波器的概念可以參考我之前寫的「淺談動平均濾波器」, http://alberthuang314.blogspot.tw/2012/08/blog-post_24.html
這還是 Motorola DSP56300 的組合語言, 是將近二十年前的產品。
Kishore Dasari, Designing with the Cortex-M4, https://www.arm.com/files/pdf/DSPConceptsM4Presentation.pdf