




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、新的体系结构上运行。Linux还利用GCC中的特性(称为扩展)实现更多功能和优化。本文讨论一些重要的扩展,讲解如何在Linux内核中使用它们。GCC当前的稳定版本(版本4.3.2)支持C标准的三个版本:InternationalOrganizationforStandardization(ISO)最初的C语言标准(ISOC89或C90)带修正1的ISOC90当前的ISOC99(这是GCC使用的默认标准,本文也假设采用这种标准)注意:本文假设使用ISOC99标准。如果指定比ISOC99版本旧的标准,那么可能无法使用本文描述的一些扩展。可以在命令行上使用-std选项指定GCC使用的实际标准。可以通
2、过GCC手册查看哪个标准版本支持哪些扩展。可以以几种方式对可用的C扩展进行分类。本文把它们分为两大类:功能性扩展提供新功能。优化扩展帮助生成更高效的代码。功能性扩展先讨论一些扩展标准C语言的GCC扩展。类型发现GCC允许通过变量的引用识别类型。这种操作支持泛型编程。在C+、Ada和Java语言等许多现代编程语言中都可以找到相似的功能。Linux使用typeof构建min和max等依赖于类型的操作。清单1演示如何使用typeof构建一个泛型宏(见./linux/include/linux/kernel.h)。清单1.使用typeof构建一个泛型宏还可以使用范围进行初始化,如下所示(见./linu
3、x/arch/cris/arch-v32/kernel/smp.c)。在#definemin(x,y)(typeof(x)_min1=(x);typeof(y)_min2=(y);(void)(&_min1=&_min2);_min1_min2?_min1:_min2;)范围扩展GCC支持范围,在C语言的许多方面都可以使用范围。其中之一是switch/case块中的case语句。在复杂的条件结构中,通常依靠嵌套的if语句实现与清单2(见./Linux/drivers/scsi/sd.c)相同的结果,但是清单2更简洁。使用switch/case也可以通过使用跳转表实现进行编译器优化。清单2.在c
4、ase语句中使用范围staticintsd_major(intmajor_idx)switch(major_idx)case0:returnSCSI_DISK0_MAJOR;case1.7:returnSCSI_DISK1_MAJOR+major_idx-1;case8.15:returnSCSI_DISK8_MAJOR+major_idx-8;default:BUG;return0;/*shutupgcc*/这个示例中,spinlock_t创建一个大小为LOCK_COUNT的数组。数组的每个元素初始化为SPIN_LOCK_UNLOCKED值。/*Vectoroflocksusedforvar
5、iousatomicoperations*/spinlock_tcris_atomic_locks=0.LOCK_COUNT-1=SPIN_LOCK_UNLOCKED;范围还支持更复杂的初始化。例如,以下代码指定数组中几个子范围的初始值。intwidths=0.9=1,10.99=2,100=3;零长度的数组在C标准中,必须定义至少一个数组元素。这个需求往往会使代码设计复杂化。但是,GCC支持零长度数组的概念,这对于结构定义尤其有用。这个概念与ISOC99中灵活的数组成员相似,但是使用不同的语法。下面的示例在结构的末尾声明一个没有成员的数组(见./Linux/drivers/IEeel394/
6、rawl394-private.h)。这允许结构中的元素引用结构实例后面紧接着的内存。在需要数量可变的数组成员时,这个特性很有用。structiso_block_storeatomic_trefcount;size_tdata_size;quadlet_tdata0;判断调用地址在许多情况下,需要判断给定函数的调用者。GCC提供用于此用途的内置函数还可以使用范围进行初始化,如下所示(见./linux/arch/cris/arch-v32/kernel/smp.c)。在还可以使用范围进行初始化,如下所示(见./linux/arch/cris/arch-v32/kernel/smp.c)。在_bu
7、iltin_return_address。这个函数通常用于调试,但是它在内核中还有许多其他用途。如下面的代码所示,_builtin_return_address接收一个称为level的参数。这个参数定义希望获取返回地址的调用堆栈级别。例如,如果指定level为0,那么就是请求当前函数的返回地址。如果指定level为1,那么就是请求进行调用的函数的返回地址,依此类推。void*_builtin_return_address(unsignedintlevel);在下面的示例中(见./linux/kernel/softirq.c),local_bh_disable函数在本地处理器上禁用软中断,从而禁
8、止在当前处理器上运行softirqs、tasklets和bottomhalves。使用_builtin_return_address捕捉返回地址,以便在以后进行跟踪时使用这个地址。voidlocal_bh_disable(void)_local_bh_disable(unsignedlong)_builtin_return_address(0);在编译时,可以使用常量检测GCC提供的一个内置函数判断一个值是否是常量。这种信息非constantfolding)优化的表达式。常有价值,因为可以构造出能够通过常量叠算(_builtin_constant_p函数用来检测常量。_builtin_cons
9、tant_p的原型如下所示。注意,因为GCC不容易证明某些值是否是常量。builtin_constant_p并不能检测出所有常量,int_builtin_constant_p(exp)Linux相当频繁地使用常量检测。在清单(见./linux/include/linux/log2.h),使用常量检测优化表达式是常量,那么就使用可以优化的常量表达式。函数把值向上取整到2的幂。3所示的示例中roundup_pow_of_two宏。如果发现如果表达式不是常量,就调用另一个宏清单3.使用常量检测优化宏函数#defineroundup_pow_of_two(n)(_builtin_constant_p(
10、n)?(n=1)?1:(1ULlen,skb-csum);if(likely(!sum)if(unlikely(skb-ip_summed=CHECKSUM_HW)netdev_rx_csum_fault(skb-dev);skb-ip_summed=CHECKSUM_UNNECESSARY;returnsum;预抓取另一种重要的性能改进方法是把必需的数据缓存在接近处理器的地方。问数据花费的时间。大多数现代处理器都有三类内存:缓存可以显著减少访一级缓存通常支持单周期访问二级缓存支持两周期访问系统内存支持更长的访问时间为了尽可能减少访问延时并由此提高性能,最好把数据放在最近的内存中。手工执行这个
11、任务称为预抓取。GCC通过内置函数builtin_prefetch支持数据的手工预抓取。在需要数据之前,使用这个函数把数据放到缓存中。如下所示,builtin_prefetch函数接收三个参数:数据的地址rw参数,使用它指明预抓取数据是为了执行读操作,还是执行写操作locality参数,使用它指定在使用数据之后数据应该留在缓存中,还是应该清除void_builtin_prefetch(constvoid*addr,intrw,intlocality);6是一个辅助函数示例,它使用内置函数的包装器(见Linux内核经常使用预抓取。通常是通过宏和包装器函数使用预抓取。清单./linux/inclu
12、de/linux/prefetch.h)。这个函数为流操作实现预抓取机制。使用这个函数通常可以减少缓存缺失和停顿,从而提高性能。清单6.范围预抓取的包装器函数#ifndefARCH_HAS_PREFETCH#defineprefetch(x)_builtin_prefetch(x)#endifstaticinlinevoidprefetch_range(void*addr,size_tlen)#ifdefARCH_HAS_PREFETCHchar*cp;char*end=addr+len;for(cp=addr;cpend;cp+=PREFETCH_STRIDE)prefetch(cp);#e
13、ndif变量属性除了本文前面讨论的函数属性之外,GCC还为变量和类型定义提供了属性。最重要的属性之一是aligned属性,它用于在内存中实现对象对齐。除了对于性能很重要之外,某些设备或硬件配置也需要对象对齐。aligned属性有一个参数,它指定所需的对齐类型。下面的示例用于软件暂停(见./Linux/arch/i386/mm/init.c)。在需要页面对齐时,定义PAGE_SIZE对象。char_nosavedataswsusp_pg_dirPAGE_SIZE_attribute_(aligned(PAGE_SIZE);清单7中的示例说明关于优化的两点:packed属性打包一个结构的元素,从而尽可能减少它们占用的空间。这意味着,如果8位)。位字段压缩为一位,而不会定义一个char变量,它占用的空间不会超过一字节(占用更多存储空间。这段源代码使用一个attribute_声明进行优化,它用逗号分隔的列表定义多个属性。清单7.结构打包和设置多个属性staticstructswsusp_headercharreservedPAGE_SIZE-20-sizeof(swp_entry_t);swp_entry_timage;charori
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学校游泳馆管理制度
- 学校营养政管理制度
- 学生上学队管理制度
- 学生用手机管理制度
- 宁洱县财务管理制度
- 安全生物柜管理制度
- 安环部综合管理制度
- 安防部工作管理制度
- 实行平安卡管理制度
- 宠物火化店管理制度
- 2024AI Agent行业研究报告
- 高中物理教学中物理实验的改进与创新
- 华为质量回溯(根因分析与纠正预防措施)模板
- 山东省烟台市牟平区(五四制)2023-2024学年八年级下学期期末语文试题(原卷版)
- 广东省广州市荔湾区统考2023-2024学年英语八下期末统考试题含答案
- 综合英语4智慧树知到答案2024年江西师范大学
- 纺织材料学智慧树知到期末考试答案章节答案2024年武汉纺织大学
- 江西省新余市2023-2024学年八年级下学期期末质量监测物理试题
- 江苏省苏州市吴江区2023-2024学年六年级下学期期末数学试题
- 麻醉科手术室感染防控培训标准
- (正式版)JTT 1490-2024 港口安全设施分类与编码
评论
0/150
提交评论