Language

Thursday, August 7, 2014

LaTeX 字型安裝筆記: Adobe Garamond Pro 字型



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 這個路徑需要其他的安裝方法。




Author: Albert Huang


Created: 2014-08-07 Thu 01:39


Emacs 24.3.1 (Org mode 8.2.1)


Validate





Wednesday, August 6, 2014

LaTeX 字型安裝筆記: URW Garamond 字型



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 字型, 不妨可以來試試這一套字型。



Author: Albert Huang

Created: 2014-08-06 Wed 22:29

Emacs 24.3.1 (Org mode 8.2.1)

Friday, August 1, 2014

在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 =\epsilon= (\epsilon) 與 =\ell= (\ell) 的問題解法





在 LaTeX 使用內建在 Acrobat Reader 裡的 Minion Pro 與 Myriad Pro 字型以及 <code>\epsilon</code> (ε) 與 <code>\ell</code> (ℓ) 的問題解法









在 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 下載以下檔案:



  1. http://mirrors.ctan.org/fonts/minionpro/enc-2.000.zip

  2. http://mirrors.ctan.org/fonts/minionpro/metrics-base.zip

  3. http://mirrors.ctan.org/fonts/minionpro/metrics-full.zip

  4. http://mirrors.ctan.org/fonts/minionpro/metrics-opticals.zip

  5. http://mirrors.ctan.org/fonts/minionpro/scripts.zip


  6. 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




兩者的差異如圖所示:





MinionPro-figures.png





其他更詳細的使用方法, 請參考 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 的排版品質。






Author: Albert Huang


Created: 2014-08-01 Fri 23:58


Emacs 24.3.1 (Org mode 8.2.1)


Validate





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 公式中的對數函數也有將比較小的數值變化放大並將比較大的數值變化縮小的功用。

Resp_linear.png

Figure 1: 線性尺度

Resp_dB.png

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 是人耳所能聽到的下限, 又因為聲音是振幅, 所以計算公式為:
\begin{equation} L_p = 20~\log_{10}\frac{P_{rms}}{P_{ref}}, P_{ref} = 20~\mu~Pa \end{equation}

聲音用 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 能夠不再那麼陌生。

Author: Albert Huang

Created: 2014-03-03 Mon 21:47

Emacs 24.3.1 (Org mode 8.2.1)

Validate

Tuesday, February 18, 2014

談談 ARM Cortex-M4F 上的 DSP 功能

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 能力的處理器中, 有幾個分類:

  1. 數位訊號處理器(Digital Signal Processor)
  2. 數位訊號控制器(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:

2

ARM® Cortex™-M4 Processor Technical Reference Manual Revision r0p1, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439d/index.html

3

有關於定點數 Q format 可以參考我之前寫的「定點數表示法」, http://alberthuang314.blogspot.tw/2012/08/blog-post.html

4

有關於 FIR 有限響應濾波器的概念可以參考我之前寫的「淺談動平均濾波器」, http://alberthuang314.blogspot.tw/2012/08/blog-post_24.html

5

這還是 Motorola DSP56300 的組合語言, 是將近二十年前的產品。

6

Kishore Dasari, Designing with the Cortex-M4, http://www.arm.com/files/pdf/dspconceptsm4presentation.pdf

Author: Albert Huang

Created: 2014-02-18 Tue 22:05

Emacs 24.3.1 (Org mode 8.2.1)

Validate