標(biāo)題: Linux 內(nèi)核中的 GCC 特性(轉(zhuǎn)) [打印本頁(yè)] 作者: dreamice 時(shí)間: 2009-04-15 21:28 標(biāo)題: Linux 內(nèi)核中的 GCC 特性(轉(zhuǎn)) Linux 內(nèi)核中的 GCC 特性(轉(zhuǎn))
M. Tim Jones, 顧問(wèn)工程師, Emulex Corp.
2009 年 4 月 07 日
Linux® 內(nèi)核使用 GNU Compiler Collection (GCC) 套件的幾個(gè)特殊功能。這些功能包括提供快捷方式和簡(jiǎn)化以及向編譯器提供優(yōu)化提示等等。了解這些特殊的 GCC 特性,學(xué)習(xí)如何在 Linux 內(nèi)核中使用它們。
GCC 和 Linux 是出色的組合。盡管它們是獨(dú)立的軟件,但是 Linux 完全依靠 GCC 在新的體系結(jié)構(gòu)上運(yùn)行。Linux 還利用 GCC 中的特性(稱為擴(kuò)展)實(shí)現(xiàn)更多功能和優(yōu)化。本文討論一些重要的擴(kuò)展,講解如何在 Linux 內(nèi)核中使用它們。
GCC 當(dāng)前的穩(wěn)定版本(版本 4.3.2)支持 C 標(biāo)準(zhǔn)的三個(gè)版本:
* International Organization for Standardization (ISO) 最初的 C 語(yǔ)言標(biāo)準(zhǔn)(ISO C89 或 C90)
* 帶修正 1 的 ISO C90
* 當(dāng)前的 ISO C99(這是 GCC 使用的默認(rèn)標(biāo)準(zhǔn),本文也假設(shè)采用這種標(biāo)準(zhǔn))
注意:本文假設(shè)使用 ISO C99 標(biāo)準(zhǔn)。如果指定比 ISO C99 版本舊的標(biāo)準(zhǔn),那么可能無(wú)法使用本文描述的一些擴(kuò)展。可以在命令行上使用 -std 選項(xiàng)指定 GCC 使用的實(shí)際標(biāo)準(zhǔn)。可以通過(guò) GCC 手冊(cè)查看哪個(gè)標(biāo)準(zhǔn)版本支持哪些擴(kuò)展(見(jiàn) 參考資料 中的鏈接)。
可應(yīng)用的版本
本文主要關(guān)注在 2.6.27.1 Linux 內(nèi)核和 GCC 的 4.3.2 版本中使用 GCC 擴(kuò)展。每個(gè) C 擴(kuò)展引用 Linux 內(nèi)核源代碼中的一個(gè)文件,可以在其中找到示例。
可以以幾種方式對(duì)可用的 C 擴(kuò)展進(jìn)行分類。本文把它們分為兩大類:
* 功能性 擴(kuò)展提供新功能。
* 優(yōu)化 擴(kuò)展幫助生成更高效的代碼。
功能性擴(kuò)展
先討論一些擴(kuò)展標(biāo)準(zhǔn) C 語(yǔ)言的 GCC 擴(kuò)展。
類型發(fā)現(xiàn)
GCC 允許通過(guò)變量的引用識(shí)別類型。這種操作支持泛型編程。在 C++、Ada 和 Java™ 語(yǔ)言等許多現(xiàn)代編程語(yǔ)言中都可以找到相似的功能。Linux 使用 typeof 構(gòu)建 min 和 max 等依賴于類型的操作。清單 1 演示如何使用 typeof 構(gòu)建一個(gè)泛型宏(見(jiàn) ./linux/include/linux/kernel.h)。
在 C 標(biāo)準(zhǔn)中,必須定義至少一個(gè)數(shù)組元素。這個(gè)需求往往會(huì)使代碼設(shè)計(jì)復(fù)雜化。但是,GCC 支持零長(zhǎng)度數(shù)組的概念,這對(duì)于結(jié)構(gòu)定義尤其有用。這個(gè)概念與 ISO C99 中靈活的數(shù)組成員相似,但是使用不同的語(yǔ)法。
下面是在 Linux 內(nèi)核中使用這些屬性的示例。deprecated 示例來(lái)自與體系結(jié)構(gòu)無(wú)關(guān)的內(nèi)核(./linux/kernel/resource.c),const 示例來(lái)自 IA64 內(nèi)核源代碼(./linux/arch/ia64/kernel/unwind.c)。
int __deprecated __check_region(struct resource
*parent, unsigned long start, unsigned long n)
static enum unw_register_index __attribute_const__
decode_abreg(unsigned char abreg, int memory)
優(yōu)化擴(kuò)展
現(xiàn)在,討論有助于生成更好的機(jī)器碼的一些 GCC 特性。
分支預(yù)測(cè)提示
在 Linux 內(nèi)核中最常用的優(yōu)化技術(shù)之一是 __builtin_expect。在開(kāi)發(fā)人員使用有條件代碼時(shí),常常知道最可能執(zhí)行哪個(gè)分支,而哪個(gè)分支很少執(zhí)行。如果編譯器知道這種預(yù)測(cè)信息,就可以圍繞最可能執(zhí)行的分支生成最優(yōu)的代碼。
void __builtin_prefetch( const void *addr, int rw, int locality );
Linux 內(nèi)核經(jīng)常使用預(yù)抓取。通常是通過(guò)宏和包裝器函數(shù)使用預(yù)抓取。清單 6 是一個(gè)輔助函數(shù)示例,它使用內(nèi)置函數(shù)的包裝器(見(jiàn) ./linux/include/linux/prefetch.h)。這個(gè)函數(shù)為流操作實(shí)現(xiàn)預(yù)抓取機(jī)制。使用這個(gè)函數(shù)通?梢詼p少緩存缺失和停頓,從而提高性能。