《现代体系结构上的UNIX系统:内核程序员的对称多处理和缓存技术(修订版)》——2.11 高速缓存的性能

简介: 虽然全面讨论高速缓存的性能超出了本书的范围,但还是可以做以下一些观察。首先,高速缓存的性能不仅取决于高速缓存的设计,而且取决于应用程序的引用模式。因此,必须谨慎地通过测试基准程序来判定高速缓存的性能以及一般化测试结果。

本节书摘来自异步社区《现代体系结构上的UNIX系统:内核程序员的对称多处理和缓存技术(修订版)》一书中的第2章,第2.11节,作者:【美】Curt Schimmel著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.11 高速缓存的性能

虽然全面讨论高速缓存的性能超出了本书的范围,但还是可以做以下一些观察。首先,高速缓存的性能不仅取决于高速缓存的设计,而且取决于应用程序的引用模式。因此,必须谨慎地通过测试基准程序来判定高速缓存的性能以及一般化测试结果。虽然很容易编写一个获得100%命中率的基准程序,但是把它们运用到实际应用中的时候,这样的结果是毫无意义的。例如,下面的程序会获得100%的高速缓存命中率:

while (1)
   ;

循环执行一次之后,所有的指令引用都会在高速缓存中命中。相反,下面的代码片段给一个数组中的每个元素都乘以常数c,因而会得到相当低的高速缓存命中率(假定数组要比高速缓存大)。

for ( j=0; j < YMAX; j++)
     for ( i=0; i < XMAX; i++)
        matrix[i][j] *= c;

因为在C语言中,数组是按行来保存的,在使用高速缓存的时候,如果数组中一行的大小超过了高速缓存行的长度(假定一开始数组没有被高速缓存),那么每次执行最里面的语句就会出现一次缺失。这样的情形尤其糟糕,因为行很长的高速缓存会读取大量从来都不会用到的数据。互换两层for循环会因为空间局部性而提高性能。即使每个元素只读取一次,高速缓存每次都要读取整整一行的事实也意味着引用连续的元素可能会产生一次命中。例外的情况是那些行很小的高速缓存,像MIPS R2000/R3000,它们的每个高速缓存行只有4字节。如果数组matrix的每个元素也是4字节,那么就没有空间局部性的好处了。

即使高速缓存的性能是依赖于应用的,在直觉上还是可以有下面的结论(虽然对于所有应用来说,它们并不一定都对,但是对于包括典型UNIX命令在内的许多应用来说,它们都是正确的)。首先,写回策略比写直通策略更可取,因为程序一般会因为时间局部性而多次修改变量。即使它们没有多次修改变量,写回高速缓存机制也往往不会增加任何性能开销,因为写直通一行或者在以后替换行的时候再写回都要花费一个存储器周期。为每一行维护一个修改位并处理写回虽然增加了复杂性,但这样做是值得的。在最差的情况下,没有时间或者空间局部性可言,有写分配能力的写回策略只会多读一次高速缓存行。完全没有局部性的情形是非常少见的,所以它们不会对性能造成明显的影响。

接下来,增加组的大小一般也会有帮助。对于小规模的高速缓存(1 KB或者更小)来说这样的做法特别有用,因为即便多个地址产生了相同的索引,它也能利用更多的高速缓存。对于非常大的高速缓存(1 MB或者更多)来说,增加组的大小就没那么重要了,因为随着行数的增加,出现一段数据替换现有的高速缓存数据的可能性也逐渐减小。

由于空间局部性,增加高速缓存行的大小一般也会对高速缓存性能有帮助。高速缓存行太长的缺点是在缺失处理期间读取数据需要开销。在小规模高速缓存的组织结构中找不到很长的高速缓存行,因为这就意味着高速缓存中的行数会更少。因此出现替换的频率就更高了。

高速缓存的性能也会受到操作系统的影响。不同的高速缓存组织结构需要不同情况的冲洗机制。有若干种技术可以用来减少必须发生的冲洗量。这很重要,因为频繁的冲洗很花时间,并且减少了有用的数据被高速缓存的时间。

相关文章
|
6月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
117 6
|
4月前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
370 78
|
6月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
183 15
Android 系统缓存扫描与清理方法分析
|
8月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
190 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
9月前
|
消息中间件 缓存 算法
基于Netty的自研流系统缓存实现挑战: 内存碎片与OOM困境
基于Netty的自研流系统缓存实现挑战: 内存碎片与OOM困境
92 1
基于Netty的自研流系统缓存实现挑战: 内存碎片与OOM困境
|
8月前
|
缓存 应用服务中间件 nginx
[nginx]proxy_cache缓存系统
[nginx]proxy_cache缓存系统
208 4
|
8月前
|
缓存 架构师 数据库
缓存系统稳定性 - 架构师峰会演讲实录
缓存系统稳定性 - 架构师峰会演讲实录
|
8月前
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
112 0
|
10月前
|
缓存 监控 负载均衡
Java一分钟之-Ehcache:分布式缓存系统
【6月更文挑战第17天】**Ehcache是Java的开源缓存库,支持本地和分布式缓存,提供负载均衡、数据复制和容错能力。常见问题包括网络分区导致的数据不一致、缓存雪崩和配置不当引起的性能瓶颈。解决策略涉及选择强一致性策略、设置合理缓存过期时间和监控调整配置。使用Ehcache需添加相关依赖,并配置分布式缓存,如示例所示,通过CacheManager创建和管理缓存。实践中,持续监控和优化配置至关重要。**
238 1
|
9月前
|
消息中间件 缓存 架构师
对抗软件复杂度问题之降低代码的复杂度,如何解决
对抗软件复杂度问题之降低代码的复杂度,如何解决