本書結(jié)合ARM架構(gòu)和Linux工具,關(guān)注以性能為導(dǎo)向的嵌入式編程,深入講解如何通過對數(shù)據(jù)、算法和存儲等層面的優(yōu)化,終實(shí)現(xiàn)性能的顯著提升。本書先講解ARM架構(gòu)和嵌入式系統(tǒng)的基礎(chǔ)知識,然后結(jié)合圖像變換、分形生成和計(jì)算機(jī)視覺等應(yīng)用案例,詳細(xì)說明不同的優(yōu)化方法。讀者可在RaspberryPi等平臺上動手運(yùn)行并比較不同算法,掌握實(shí)踐技巧。本書適合作為本科或研究生嵌入式系統(tǒng)課程的教材,也適合從事相關(guān)開發(fā)工作的程序員參考。
前 言Embedded Systems: ARM Programming and Optimization多年來,我一直工作在可重構(gòu)計(jì)算領(lǐng)域。可重構(gòu)計(jì)算領(lǐng)域的目標(biāo)是開發(fā)有效的工具和方法,以促進(jìn)現(xiàn)場可編程門陣列(FPGA)作為協(xié)處理器在高性能計(jì)算機(jī)系統(tǒng)中的使用。 這個學(xué)科的主要挑戰(zhàn)之一是“程序設(shè)計(jì)問題”,即FPGA的實(shí)際應(yīng)用從根本上受到煩瑣和容易出錯的程序模型的限制。這個問題值得我們特別關(guān)注,因?yàn)樗羌夹g(shù)優(yōu)勢所導(dǎo)致的結(jié)果:FPGA實(shí)現(xiàn)了細(xì)粒度并發(fā)操作,這樣程序員可以控制芯片中每個電路的同步行為。然而,這種控制還要求程序員管理細(xì)粒度的控制,例如片上存儲使用和路由擁塞。另一方面,CPU程序只需要考慮每一行代碼的可能CPU狀態(tài),片上資源在硬件運(yùn)行時將自動管理。 最近我意識到,現(xiàn)代嵌入式系統(tǒng)可能很快就會面臨類似的程序設(shè)計(jì)問題。電池技術(shù)仍然相對滯后,并且在用近6年時間實(shí)現(xiàn)了從65nm到28nm的制造工藝后,摩爾定律的發(fā)展速度開始明顯減緩。與此同時,消費(fèi)者已經(jīng)開始期待嵌入式系統(tǒng)功能的不斷進(jìn)步,例如能夠在一副眼鏡上的處理器中運(yùn)行實(shí)時增強(qiáng)現(xiàn)實(shí)(AR)軟件。 鑒于這些能源效率和性能的要求,許多嵌入式處理器廠商正在為微體系結(jié)構(gòu)尋求更節(jié)能的方法,并經(jīng)常涉及對并行類型的選擇,而這一類型是不能從軟件中自動提取的。這就需要程序員協(xié)助編寫并行代碼。這帶來了很多問題:程序員要在資源和能量均有限的平臺上兼顧功能和性能,要知道,在這個平臺上可能包括從多核到GPU著色器單元等各種并行資源。 許多大學(xué)已經(jīng)開展了“統(tǒng)一”的并行編程課程,這些課程涵蓋了從分布式系統(tǒng)到多核處理器的并行編程系列。然而,教授這類主題的角度通常是高性能計(jì)算而非嵌入式計(jì)算。 隨著最近Raspberry Pi等先進(jìn)嵌入式平臺的爆發(fā),我意識到需要開發(fā)針對嵌入式系統(tǒng)性能的編程課程,這些課程應(yīng)涵蓋從計(jì)算機(jī)體系結(jié)構(gòu)到并行編程的相關(guān)主題。我也想納入一些有趣的相關(guān)項(xiàng)目和課程的案例研究,這樣可以避開枯燥的傳統(tǒng)嵌入式系統(tǒng)課程項(xiàng)目(例如閃爍的LED)和并行編程課程(例如編寫和優(yōu)化快速傅里葉變換)。 在自己的嵌入式系統(tǒng)課程中使用這些想法時,我經(jīng)常發(fā)現(xiàn)學(xué)生們會爭相實(shí)現(xiàn)最快的圖像旋轉(zhuǎn)或最快的曼德布羅特集合生成器。這種競爭也激發(fā)了學(xué)生的學(xué)習(xí)熱情。 如何使用本書本書面向初級或高級本科計(jì)算機(jī)科學(xué)或計(jì)算機(jī)工程課程。雖然嵌入式系統(tǒng)課程可能關(guān)注控制理論、機(jī)器人技術(shù)、低功耗設(shè)計(jì)、實(shí)時系統(tǒng)或其他相關(guān)的主題,但本書旨在介紹輕量級片上系統(tǒng)嵌入式處理器上的以性能為導(dǎo)向的編程。 本書應(yīng)該結(jié)合Raspberry Pi等嵌入式設(shè)計(jì)平臺一起使用,這樣學(xué)生可以評估書中所述的實(shí)踐和方法。 在使用本書時,學(xué)生應(yīng)該預(yù)先學(xué)習(xí)C編程語言和Linux操作系統(tǒng)的基本知識,并了解諸如任務(wù)同步等基本的并發(fā)。 教輔支持可訪問網(wǎng)站booksite.elsevier.com/9780128003428查看本書的幻燈片、習(xí)題答案和勘誤表。 致 謝Embedded Systems: ARM Programming and Optimization感謝幫助我完成本書的幾位學(xué)生。 2013年春季和夏季,本科生Benjamin Morgan、Jonathan Kilby、Shawn Weaver、Justin Robinson以及Amadeo Bellotti評估了Raspberry Pi Broadcom BCM2835和Xilinx Zynq 7020上的DMA控制器和性能監(jiān)控單元。 2014年夏季,本科生Daniel Clements幫助我開發(fā)了在ARM11、ARM Cortex A9和ARM Cortex A15上使用Linux perf_event的統(tǒng)一方法。Daniel還評估了圖像技術(shù)的OpenCL運(yùn)行時,以及描述了在ODROID XU Exynos 5平臺上的PowerVR 544 GPU的性能特點(diǎn)。 2015年夏季,本科生Friel“Scottie”Scott幫助我評估了ODROID XU3平臺上的Mali T628 GPU,并且校對了第5章的內(nèi)容。 許多關(guān)于計(jì)算機(jī)視覺算法存儲優(yōu)化的見解來自我的研究生Fan Zhang的關(guān)于德州儀器關(guān)鍵數(shù)字信號處理器架構(gòu)的自動優(yōu)化模板循環(huán)的論文。 感謝以下評論者,他們在本書的編寫過程中提供了反饋、見解以及有用的建議: Miriam Leeser,美國東北大學(xué)Larry D. Pyeatt,美國南達(dá)科他礦業(yè)理工學(xué)院Andrew N. Sloss,美國華盛頓大學(xué),同時在ARM公司做顧問工程師Amr Zaky,美國圣塔克拉拉大學(xué)感謝Morgan Kaufmann出版公司,感謝Nate McFadden在整個寫作過程中給予我的不斷鼓勵和無限耐心。特別感謝Nate對于本書內(nèi)容所持的開放和靈活的態(tài)度,這使我在寫作時能夠不斷跟進(jìn)新發(fā)布的基于ARM的嵌入式開發(fā)平臺。也要感謝Sujatha Thirugnana Sambandam的細(xì)心編輯,還要感謝Mark Rogers為本書設(shè)計(jì)封面。
Jason D. Bakos,美國南卡羅來納大學(xué)計(jì)算機(jī)科學(xué)與工程系副教授,研究方向包括高性能計(jì)算、異構(gòu)網(wǎng)絡(luò)和嵌入式計(jì)算機(jī)系統(tǒng)等。擁有2項(xiàng)專利,發(fā)表了30余篇學(xué)術(shù)論文。2009年曾獲得美國國家科學(xué)基金(NSF)事業(yè)獎,現(xiàn)為ACM會刊《可重構(gòu)技術(shù)與系統(tǒng)》的副主編。
目 錄Embedded Systems: ARM Programming and Optimization出版者的話譯者序前言致謝第1章Linux/ARM嵌入式平臺 11.1以性能為導(dǎo)向的編程 21.2ARM技術(shù) 31.3ARM簡史 41.4ARM編程 41.5ARM體系集架構(gòu) 51.5.1ARM通用寄存器 51.5.2狀態(tài)寄存器 61.5.3內(nèi)存尋址模式 71.5.4GNU ARM匯編 81.6匯編優(yōu)化1:排序 81.6.1參考實(shí)現(xiàn) 81.6.2匯編實(shí)現(xiàn) 91.6.3結(jié)果驗(yàn)證 111.6.4分析編譯器生成的代碼 131.7匯編優(yōu)化2:位操作 151.8代碼優(yōu)化目標(biāo) 161.8.1減少執(zhí)行指令數(shù) 161.8.2降低平均CPI 161.9使用性能計(jì)數(shù)器的運(yùn)行時分析 181.9.1ARM性能監(jiān)控單元 181.9.2Linux Perf_Event 181.9.3性能計(jì)數(shù)器的基礎(chǔ)架構(gòu) 191.10檢測存儲器帶寬 221.11性能測試結(jié)果 251.12性能界限 251.13基本指令集 261.13.1整型算術(shù)指令 261.13.2按位邏輯指令 261.13.3移位指令 271.13.4移動指令 271.13.5加載和存儲指令 281.13.6比較指令 281.13.7分支指令 291.13.8浮點(diǎn)指令 291.14小結(jié) 30習(xí)題 31第2章多核和數(shù)據(jù)層優(yōu)化:OpenMP和SIMD 332.1本書所涉及的優(yōu)化技術(shù) 332.2阿姆達(dá)爾定律 342.3測試內(nèi)核:多項(xiàng)式評估 352.4使用多核:OpenMP 372.4.1OpenMP指令 372.4.2范圍 392.4.3其他OpenMP指令 422.4.4OpenMP同步 422.4.5調(diào)試OpenMP代碼 442.4.6OpenMP并行循環(huán)編譯指令 462.4.7OpenMP與性能計(jì)數(shù)器 482.4.8OpenMP支持霍納內(nèi)核 482.5性能界限 482.6性能分析 492.7GCC中的內(nèi)聯(lián)匯編語言 502.8優(yōu)化1:降低每f?lop的指令數(shù) 512.9優(yōu)化2:降低CPI 542.9.1軟件流水線 542.9.2軟件流水線的霍納方法 572.10優(yōu)化3:使用SIMD時的每指令多f?lop 632.10.1ARM11的VFP短向量指令 652.10.2ARM Cortex的NEON指令 672.10.3NEON內(nèi)聯(lián)函數(shù) 692.11小結(jié) 70習(xí)題 71第3章算法優(yōu)化和Linux幀緩沖 723.1Linux幀緩沖 723.2仿射圖像變換 743.3雙線性插值 743.4浮點(diǎn)圖像變換 753.4.1加載圖像 763.4.2渲染幀 783.5浮點(diǎn)性能分析 823.6定點(diǎn)運(yùn)算 823.6.1定點(diǎn)與浮點(diǎn):準(zhǔn)確度 833.6.2定點(diǎn)與浮點(diǎn):范圍 833.6.3定點(diǎn)與浮點(diǎn):精度 833.6.4使用定點(diǎn) 843.6.5高效定點(diǎn)加法 843.6.6高效定點(diǎn)乘法 873.6.7確定小數(shù)點(diǎn)的位置 893.6.8圖像變換的范圍和準(zhǔn)確度要求 903.6.9將浮點(diǎn)值轉(zhuǎn)換為定點(diǎn)值的運(yùn)算 903.7定點(diǎn)性能 923.8實(shí)時分形生成 923.8.1像素著色 943.8.2放大 943.8.3范圍和準(zhǔn)確度要求 953.9小結(jié) 96習(xí)題 96第4章存儲優(yōu)化和視頻處理 994.1模板循環(huán) 994.2模板案例:均值濾波器 1004.3可分離濾波器 1004.3.1高斯模糊 1014.3.2Sobel濾波器 1034.3.3Harris角點(diǎn)檢測器 1044.3.4Lucas-Kanade光流 1064.4二維濾波器的存儲訪問行為 1084.4.1二維數(shù)據(jù)展示 1084.4.2按行濾波 1084.4.3按列濾波 1094.5循環(huán)分塊 1104.6分塊和模板暈區(qū) 1124.7二維濾波實(shí)現(xiàn)案例 1124.8視頻幀的捕獲和轉(zhuǎn)換 1164.8.1YUV和色度抽樣 1164.8.2將分塊導(dǎo)出到幀緩沖區(qū) 1184.9Video4Linux驅(qū)動和API 1194.10使用二維分塊濾波器 1224.11應(yīng)用可分離的二維分塊濾波器 1234.12頂層循環(huán) 1244.13性能結(jié)果 1244.14小結(jié) 124習(xí)題 125第5章利用OpenCL進(jìn)行嵌入式異構(gòu)編程 1275.1GPU微體系結(jié)構(gòu) 1285.2OpenCL 1285.3OpenCL編程模型、語法及摘要 1295.3.1主機(jī)/設(shè)備編程模型 1295.3.2錯誤檢查 1305.3.3平臺層:初始化平臺 1315.3.4平臺層:初始化設(shè)備 1335.3.5平臺層:初始化上下文 1355.3.6平臺層:內(nèi)核控制 1365.3.7平臺層:內(nèi)核編譯 1375.3.8平臺層:設(shè)備存儲分配 1405.4內(nèi)核工作負(fù)荷分配 1415.4.1設(shè)備存儲區(qū) 1425.4.2內(nèi)核參數(shù) 1435.4.3內(nèi)核向量化 1455.4.4霍納內(nèi)核的參數(shù)空間 1465.4.5內(nèi)核屬性 1475.4.6內(nèi)核調(diào)度 1475.5霍納方法的OpenCL實(shí)現(xiàn):設(shè)備碼 1525.6性能結(jié)果 1565.6.1參數(shù)探索 1565.6.2工作組數(shù) 1565.6.3工作組大小 1575.6.4向量大小 1575.7小結(jié) 158習(xí)題 158附錄A 為Raspberry Pi 1的Raspbian系統(tǒng)添加PMU支持 160附錄B NEON內(nèi)聯(lián)函數(shù)指令 163附錄C OpenCL參考 175