來(lái)源:百問(wèn)網(wǎng)
作者:韋東山
本文字?jǐn)?shù):3408,閱讀時(shí)長(zhǎng):5分鐘
使用 buildroot 來(lái)給 ARM 板編譯程序、編譯庫(kù)會(huì)很簡(jiǎn)單,以后系統(tǒng)講解 buildroot 時(shí)再使用 buildroot?,F(xiàn)在我們還是手工交叉編譯 freetype,這種方法在編譯、安裝一些小程序時(shí)很有用。
1. 編譯程序時(shí)去哪找頭文件?
系統(tǒng)目錄:就是交叉編譯工具鏈里的某個(gè) include 目錄;
也可以自己指定:編譯時(shí)用 “ -I dir ”選項(xiàng)指定。
2. 鏈接時(shí)去哪找?guī)煳募?/strong>
系統(tǒng)目錄:就是交叉編譯工具鏈里的某個(gè) lib 目錄;
也可以自己指定:鏈接時(shí)用 “ -L dir ”選項(xiàng)指定。
3. 運(yùn)行時(shí)去哪找?guī)煳募?/strong>
系統(tǒng)目錄:就是板子上的/lib、/usr/lib 目錄;
也可以自己指定:運(yùn)行程序用環(huán)境變量 LD_LIBRARY_PATH 指定。
4. 運(yùn)行時(shí)不需要頭文件,所以頭文件不用放到板子上
1. 頭文件問(wèn)題
編譯時(shí)找不到頭文件。在程序中這樣包含頭文件:#include <xxx.h>
對(duì)于尖括號(hào)里的頭文件,去哪里找它?
系統(tǒng)目錄:就是交叉編譯工具鏈里的某個(gè) include 目錄;
也可以自己指定:編譯時(shí)用 “ -I dir ”選項(xiàng)指定。
怎么確定“系統(tǒng)目錄”?
執(zhí)行下面命令確定目錄:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v -
它會(huì)列出頭文件目錄、庫(kù)目錄(LIBRARY_PATH)。
你需要在頭文件目錄中確定有沒(méi)有這個(gè)文件,或是自己指定頭文件目錄。
2. 庫(kù)文件問(wèn)題
鏈接程序時(shí)如果有這樣的提示:undefined reference to `xxx',它表示 xxx 函數(shù)未定義。
那么解決方法有 2:
① 去寫(xiě)出這個(gè)函數(shù)
② 或是使用庫(kù)函數(shù),那需要在鏈接時(shí)指定庫(kù)
怎么指定庫(kù)?想鏈接 libabc.so,那鏈接時(shí)加上:-labc。
庫(kù)在哪里?
① 系統(tǒng)目錄:就是交叉編譯工具鏈里的某個(gè) lib 目錄
② 也可以自己指定:鏈接時(shí)用 “ -L dir ”選項(xiàng)指定
怎么確定“系統(tǒng)目錄”?執(zhí)行下面命令確定目錄:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v –
它會(huì)列出頭文件目錄、庫(kù)目錄(LIBRARY_PATH),你編譯出庫(kù)文件時(shí),可以把它放入系統(tǒng)庫(kù)目錄。
3. 運(yùn)行問(wèn)題
運(yùn)行程序時(shí)找不到庫(kù):
error while loading shared libraries: libxxx.so:
cannot open shared object file: No such file or directory
找不到庫(kù),庫(kù)在哪?
① 系統(tǒng)目錄:就是板子上的/lib、/usr/lib 目錄
② 也可以自己指定:
運(yùn)行程序用環(huán)境變量 LD_LIBRARY_PATH 指定,執(zhí)行以下的命令:
export LD_LIBRARY_PATH=/xxx_dir ; ./test
或
LD_LIBRARY_PATH=/xxx_dir ./test
如果交叉編輯工具鏈的前綴是 arm-buildroot-linux-gnueabihf-,比如 arm-buildroot-linux
gnueabihf-gcc,交叉編譯開(kāi)源軟件時(shí),如果它里面有 configure,萬(wàn)能命令如下:
./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
make
make install
就可以在當(dāng)前目錄的 tmp 目錄下看見(jiàn) bin, lib, include 等目錄,里面存有可執(zhí)行程序、庫(kù)、頭文件。
1. 把頭文件、庫(kù)文件放到工具鏈目錄里
如果你編譯的是一個(gè)庫(kù),請(qǐng)把得到的頭文件、庫(kù)文件放入工具鏈的 include、lib 目錄里。別的程序要
使用這些頭文件、庫(kù)時(shí),會(huì)很方便。
工具鏈里可能有多個(gè) include、lib 目錄,放到哪里去?
執(zhí)行下面命令來(lái)確定目錄:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v –
它會(huì)列出頭文件目錄、庫(kù)目錄(LIBRARY_PATH)。
2. 把庫(kù)文件放到板子上的/lib 或/usr/lib 目錄里
程序在板子上運(yùn)行時(shí),需要用到板子上/lib 或/usr/lib 下的庫(kù)文件;程序運(yùn)行時(shí)不需要頭文件。
使用 GIT 下載所有源碼后,本節(jié)源碼位于如下目錄:
01_all_series_quickstart\
04_嵌入式 Linux 應(yīng)用開(kāi)發(fā)基礎(chǔ)知識(shí)\source\10_freetype\
freetype-2.10.2.tar.xz
libpng-1.6.37.tar.xz
本節(jié)文檔以 STM32MP157 開(kāi)發(fā)板,對(duì)于其他開(kāi)發(fā)板:工具鏈可能不一樣,請(qǐng)靈活變通。
1. 確定頭文件、庫(kù)文件在工具鏈中的目錄
以 STM32MP157 開(kāi)發(fā)板為例,它的工具鏈?zhǔn)?arm-buildroot-linux-gnueabihf-gcc,可以執(zhí)行以下命令:
echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v -
可以確定頭文件的系統(tǒng)目錄為:
/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
庫(kù)文件的系統(tǒng)目錄為:
/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib
2. 交叉編譯、安裝 libpng
freetype 依賴(lài)于 libpng,所以需要先編譯、安裝 libpng。命令如下:
book@PC$ tar xJf libpng-1.6.37.tar.xz
book@PC$ cd libpng-1.6.37
book@PC$ ./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
book@PC$ make
book@PC$ make install
book@PC$ cd tmp
book@PC$ cp include/* -rf /home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
book@PC$ cp lib/* -rfd /home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib
3. 交叉編譯、安裝 freetype
命令如下:
book@PC$ tar xJf freetype-2.10.2.tar.xz
book@PC$ cd freetype-2.10.2
book@PC$ ./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
book@PC$ make
book@PC$ make install
book@PC$ cd tmp
book@PC$ cp include/* -rf /home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
book@PC$ cp lib/* -rfd /home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib
「新品首發(fā)」STM32MP157開(kāi)發(fā)板火爆預(yù)售!首批僅300套
本文是通過(guò)學(xué)習(xí)極客時(shí)間專(zhuān)欄《Linux性能優(yōu)化實(shí)戰(zhàn)》05 | 基礎(chǔ)篇:某個(gè)應(yīng)用的CPU使用率居然達(dá)到100%,我該怎么辦?
***為了維護(hù) CPU 時(shí)間,Linux 通過(guò)事先定義的節(jié)拍率(內(nèi)核中表示為 HZ),觸發(fā)時(shí)間中斷,并使用全局變量 Jiffies 記錄了開(kāi)機(jī)以來(lái)的節(jié)拍數(shù)。每發(fā)生一次時(shí)間中斷,Jiffies 的值就加 1。
節(jié)拍率 HZ 是內(nèi)核的可配選項(xiàng),可以設(shè)置為 100、250、1000 等。不同的系統(tǒng)可能設(shè)置不同數(shù)值,你可以通過(guò)查詢(xún) /boot/config 內(nèi)核選項(xiàng)來(lái)查看它的配置值。比如在我的系統(tǒng)中,節(jié)拍率設(shè)置成了 250,也就是每秒鐘觸發(fā) 250 次時(shí)間中斷。
$ grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250
同時(shí),正因?yàn)楣?jié)拍率 HZ 是內(nèi)核選項(xiàng),所以用戶(hù)空間程序并不能直接訪(fǎng)問(wèn)。為了方便用戶(hù)空間程序,內(nèi)核還提供了一個(gè)用戶(hù)空間節(jié)拍率 USERHZ,它總是固定為 100,也就是 1/100 秒。這樣,用戶(hù)空間程序并不需要關(guān)心內(nèi)核中 HZ 被設(shè)置成了多少,因?yàn)樗吹降目偸枪潭ㄖ?USERHZ。
Linux 通過(guò) /proc 虛擬文件系統(tǒng),向用戶(hù)空間提供了系統(tǒng)內(nèi)部狀態(tài)的信息,而 /proc/stat 提供的就是系統(tǒng)的 CPU 和任務(wù)統(tǒng)計(jì)信息。比方說(shuō),如果你只關(guān)注 CPU 的話(huà),可以執(zhí)行下面的命令:
# 只保留各個(gè)CPU的數(shù)據(jù)
$ cat /proc/stat | grep ^cpu
cpu 280580 7407 286084 172900810 83602 0 583 0 0 0
cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0
cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0
這里的輸出結(jié)果是一個(gè)表格。其中,第一列表示的是 CPU 編號(hào),如 cpu0、cpu1 ,而第一行沒(méi)有編號(hào)的 cpu ,表示的是所有 CPU 的累加。其他列則表示不同場(chǎng)景下 CPU 的累加節(jié)拍數(shù),它的單位是 USER_HZ,也就是 10 ms(1/100 秒),所以這其實(shí)就是不同場(chǎng)景下的 CPU 時(shí)間。
當(dāng)然,這里每一列的順序并不需要你背下來(lái)。你只要記住,有需要的時(shí)候,查詢(xún) man proc 就可以。不過(guò),你要清楚 man proc 文檔里每一列的涵義,它們都是 CPU 使用率相關(guān)的重要指標(biāo),你還會(huì)在很多其他的性能工具中看到它們。下面,我來(lái)依次解讀一下。
top 和 ps 是最常用的性能分析工具:top 顯示了系統(tǒng)總體的 CPU 和內(nèi)存使用情況,以及各個(gè)進(jìn)程的資源使用情況。ps 則只顯示了每個(gè)進(jìn)程的資源使用情況。
# 默認(rèn)每3秒刷新一次
$ top
top - 11:58:59 up 9 days, 22:47, 1 user, load average: 0.03, 0.02, 0.00
Tasks: 123 total, 1 running, 72 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8169348 total, 5606884 free, 334640 used, 2227824 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 7497908 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 78088 9288 6696 S 0.0 0.1 0:16.83 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.05 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
...
這個(gè)輸出結(jié)果中,top 默認(rèn)顯示的是所有 CPU 的平均值,這個(gè)時(shí)候你只需要按下數(shù)字 1 ,就可以切換到每個(gè) CPU 的使用率了。
繼續(xù)往下看,空白行之后是進(jìn)程的實(shí)時(shí)信息,每個(gè)進(jìn)程都有一個(gè) %CPU 列,表示進(jìn)程的 CPU 使用率。它是用戶(hù)態(tài)和內(nèi)核態(tài) CPU 使用率的總和,包括進(jìn)程用戶(hù)空間使用的 CPU、通過(guò)系統(tǒng)調(diào)用執(zhí)行的內(nèi)核空間 CPU 、以及在就緒隊(duì)列等待運(yùn)行的 CPU。在虛擬化環(huán)境中,它還包括了運(yùn)行虛擬機(jī)占用的 CPU。
用 pidstat 吧,它正是一個(gè)專(zhuān)門(mén)分析每個(gè)進(jìn)程 CPU 使用情況的工具。下面的 pidstat 命令,就間隔 1 秒展示了進(jìn)程的 5 組 CPU 使用率,包括:
# 每隔1秒輸出一組數(shù)據(jù),共輸出5組
$ pidstat 1 5
15:56:02 UID PID %usr %system %guest %wait %CPU CPU Command
15:56:03 0 15006 0.00 0.99 0.00 0.00 0.99 1 dockerd
...
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 15006 0.00 0.99 0.00 0.00 0.99 - dockerd
使用 perf 分析 CPU 性能問(wèn)題,我來(lái)說(shuō)兩種最常見(jiàn)、也是我最喜歡的用法。
第一種常見(jiàn)用法是 perf top,類(lèi)似于 top,它能夠?qū)崟r(shí)顯示占用 CPU 時(shí)鐘最多的函數(shù)或者指令,因此可以用來(lái)查找熱點(diǎn)函數(shù),使用界面如下所示:
$ perf top
Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399
Overhead Shared Object Symbol
7.28% perf [.] 0x00000000001f78a4
4.72% [kernel] [k] vsnprintf
4.32% [kernel] [k] module_get_kallsym
3.65% [kernel] [k] _raw_spin_unlock_irqrestore
...
輸出結(jié)果中,第一行包含三個(gè)數(shù)據(jù),分別是采樣數(shù)(Samples)、事件類(lèi)型(event)和事件總數(shù)量(Event count)。比如這個(gè)例子中,perf 總共采集了 833 個(gè) CPU 時(shí)鐘事件,而總事件數(shù)則為 97742399。
再往下看是一個(gè)表格式樣的數(shù)據(jù),每一行包含四列,分別是:
$ perf record # 按Ctrl+C終止采樣
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.452 MB perf.data (6093 samples) ]
$ perf report # 展示類(lèi)似于perf top的報(bào)告
測(cè)試一下這個(gè) Nginx 服務(wù)的性能
# 并發(fā)10個(gè)請(qǐng)求測(cè)試Nginx性能,總共測(cè)試100個(gè)請(qǐng)求
$ ab -c 10 -n 10000 http://192.168.0.10:10000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
...
Requests per second: 11.63 [#/sec] (mean)
Time per request: 859.942 [ms] (mean)
...
新開(kāi)一個(gè)終端運(yùn)行 top 命令,并按下數(shù)字 1 ,切換到每個(gè) CPU 的使用率:
$ top
怎么知道是 php-fpm 的哪個(gè)函數(shù)導(dǎo)致了 CPU 使用率升高呢?我們來(lái)用 perf 分析一下。在第一個(gè)終端運(yùn)行下面的 perf 命令:
# -g開(kāi)啟調(diào)用關(guān)系分析,-p指定php-fpm的進(jìn)程號(hào)21515
$ perf top -g -p 21515
CPU 使用率是最直觀和最常用的系統(tǒng)性能指標(biāo),更是我們?cè)谂挪樾阅軉?wèn)題時(shí),通常會(huì)關(guān)注的第一個(gè)指標(biāo)。所以我們更要熟悉它的含義,尤其要弄清楚用戶(hù)(%user)、Nice(%nice)、系統(tǒng)(%system) 、等待 I/O(%iowait) 、中斷(%irq)以及軟中斷(%softirq)這幾種不同 CPU 的使用率。比如說(shuō):
本文由博客一文多發(fā)平臺(tái) https://openwrite.cn?from=article_bottom 發(fā)布!
友情鏈接: 餐飲加盟
地址:北京市海淀區(qū) 電話(huà):010- 郵箱:@126.com
備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有