《现代体系结构上的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或者更多)来说,增加组的大小就没那么重要了,因为随着行数的增加,出现一段数据替换现有的高速缓存数据的可能性也逐渐减小。

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

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

相关文章
|
2月前
|
SQL 缓存 开发框架
分享一个 .NET EF6 应用二级缓存提高性能的方法
分享一个 .NET EF6 应用二级缓存提高性能的方法
|
5天前
|
存储 缓存 NoSQL
解决Redis缓存击穿问题的技术方法
解决Redis缓存击穿问题的技术方法
20 2
|
8天前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
15 1
|
11天前
|
缓存 监控 负载均衡
在使用CDN时,如何配置缓存规则以优化性能
在使用CDN时,如何配置缓存规则以优化性能
|
23天前
|
缓存 JavaScript 中间件
优化Express.js应用程序性能:缓存策略、请求压缩和路由匹配
在开发Express.js应用时,采用合理的缓存策略、请求压缩及优化路由匹配可大幅提升性能。本文介绍如何利用`express.static`实现缓存、`compression`中间件压缩响应数据,并通过精确匹配、模块化路由及参数化路由提高路由处理效率,从而打造高效应用。
65 5
|
25天前
|
缓存 运维 NoSQL
二级缓存架构极致提升系统性能
本文详细阐述了如何通过二级缓存架构设计提升高并发下的系统性能。
|
1月前
|
缓存 NoSQL Java
揭秘性能提升的超级武器:掌握Hibernate二级缓存策略!
【9月更文挑战第3天】在软件开发中,性能优化至关重要。使用Hibernate进行数据持久化的应用可通过二级缓存提升数据访问速度。一级缓存随Session生命周期变化,而二级缓存是SessionFactory级别的全局缓存,能显著减少数据库访问次数,提高性能。要启用二级缓存,需在映射文件或实体类上添加相应配置。然而,并非所有场景都适合使用二级缓存,需根据业务需求和数据变更频率决定。此外,还可与EhCache、Redis等第三方缓存集成,进一步增强缓存效果。合理运用二级缓存策略,有助于大幅提升应用性能。
53 5
|
1月前
|
存储 缓存 前端开发
缓存技术在软件开发中的应用与优化策略
缓存技术在软件开发中的应用与优化策略
|
2月前
|
缓存 NoSQL Java
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
Spring Cache 是 Spring 提供的简易缓存方案,支持本地与 Redis 缓存。通过添加 `spring-boot-starter-data-redis` 和 `spring-boot-starter-cache` 依赖,并使用 `@EnableCaching` 开启缓存功能。JetCache 由阿里开源,功能更丰富,支持多级缓存和异步 API,通过引入 `jetcache-starter-redis` 依赖并配置 YAML 文件启用。Layering Cache 则提供分层缓存机制,需引入 `layering-cache-starter` 依赖并使用特定注解实现缓存逻辑。
355 1
SpringBoot的三种缓存技术(Spring Cache、Layering Cache 框架、Alibaba JetCache 框架)
|
2月前
|
存储 缓存 分布式计算
如何在 PySpark 中缓存数据以提高性能?
【8月更文挑战第13天】
104 8