文章目录
-
- [__read_mostly 介绍](#__read_mostly 介绍)
-
- [__read_mostly 在 linux 中的使用](#__read_mostly 在 linux 中的使用)
- [.data.read_mostly 介绍](#.data.read_mostly 介绍)
__read_mostly 介绍
__read_mostly
是一个在Linux内核编程中用到的宏定义,这是一个gcc编译器的属性,用于告诉编译器此变量主要用于读取,很少进行写入,最好将此变量放在具有相同特性的变量附近。使用这个宏可以优化程序在运行时的缓存性能,因为处理器会缓存经常读取的部分。
这个宏在arm gcc中和其他平台的gcc编译器中都有同样的作用。
以下是一个简单的使用示例:
c
static int __read_mostly my_variable = 0;
在这个示例中,my_variable
被声明为一个主要用于读取的静态变量。这意味着在大多数情况下,my_variable
的值将被读取,而不是写入。通过这种方式,编译器可以进行一些优化,提高代码执行的效率。
__read_mostly 在 linux 中的使用
在 arch/arm/kernel/process.c
中有如下定义:
c
unsigned logn stack_chk_guard __read_mostly
参考网上资料了解到 __read_mostly
修饰的变量放在定义为存放在 .data.read_mostly
段中。
c
#if defined(CONFIG_X86) || defined(CONFIG_SPARC64)
#define __read_mostly __attribute__((__section__(".data.read_mostly")))
#else
#define __read_mostly
#endif
Linux 内核被加载时,__read_mostly
修饰的数据将自动被存放到 Cache 中,以提高整个系统的执行效率。
如果所在的平台 没有 Cache,或者虽然有Cache,但并不提供存放数据的接口(也就是并不允许人工放置数据在Cache中) ,这样定义为 __read_mostly
类型的数据将不能存放在Linux内核中,甚至也不能够被加载到系统内存去执行,将造成Linux 内核启动失败。
解决的方法有两种:
- 修改
include/asm/cache.h
中的__ready_mostly
定义为:#define __read_mostly
- 修改
arch/xxx/kernel/vmlinux.S
,将.data.read_mostly
段的位置到实际内存空间中去,例如放置在.data
段之后等等。
.data.read_mostly 介绍
.data.read_mostly
是Linux内核中的一个特殊的数据段。这个段用于存放被__read_mostly
宏标记的变量。这些变量主要用于读取,很少进行写入,所以将它们放在同一个区域可以优化处理器的缓存性能。
在Linux内核编译过程中,GCC编译器会根据__read_mostly
宏的标记,将对应的变量放在.data.read_mostly
数据段中。这样,处理器在进行内存访问时,可以把这个段的数据预先加载到缓存中,从而提高访问效率。
需要注意的是,使用__read_mostly
标记并不意味着这个变量永远不会被写入,而只是一个优化建议,指示编译器这个变量在大部分时间里是被读取的,写入操作相对较少。