Linux访存性能测试:分析访存对CPU性能的影响

0. 引言

在嵌入式系统开发中,性能是关键的考虑因素之一。本文将深入分析ARM开发板的访存性能,并探讨访存如何影响CPU性能。
前置文章: 如何使用perf 统计cpu和内存?

测试ARM开发板CPU基本参数

4 cortex-A53
L1i=32KB L1d=32KB
L2=1MB shared

访存性能对CPU性能的统计方法

perf是Linux上一个强大的性能分析工具,可以用来收集硬件性能计数器的数据。

  • l2d_cache_refilll2d_cache_wb 通常通过L2缓存控制器中的计数器进行测量。这些计数器会跟踪从L2缓存读取和写入数据的次数。
  • cycles 通常通过CPU时钟计数器进行测量。该计数器会跟踪CPU执行的指令周期数。
  • insts 通常通过指令计数器进行测量。该计数器会跟踪执行的指令总数。
  • IPC 可以通过以下公式计算:
    IPC = insts / cycles
    
  • 访存/指令 可以通过以下公式计算:
    访存/指令 = (l2d_cache_refill + l2d_cache_wb) / insts
    

示例

以下是一个使用perf工具测量上述性能指标的示例:

perf stat -e l2d_cache_refill,l2d_cache_wb,cycles,instructions -p <pid>

其中,<pid>是要分析的进程的ID。该命令将输出以下结果:

l2d_cache_refill      l2d_cache_wb     cycles       instructions     IPC      
       14846205.00       23929355.00  7457445631.00  5885430181.00  0.79

您可以使用这些结果来计算IPC访存/指令

1. 测试代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

#define CACHE_LINE_SIZE 64 // 缓存行大小,通常为64字节

typedef struct {
    uint64_t begin;   // 起始地址
    uint64_t end;     // 结束地址
    uint32_t step;   // 每次读取的跨度(以缓存行大小为单位)
} test_config_t;

void test_access(test_config_t *config) {
    uint64_t *ptr = (uint64_t *)config->begin;
    uint64_t size = config->end - config->begin;
    uint32_t step = config->step;

    clock_t start = clock();

    for (uint64_t i = 0; i < size; i += step * CACHE_LINE_SIZE) {
        uint64_t value = *ptr; // 模拟访存操作
        ptr += step;
    }

    clock_t end = clock();
    double duration = (double)(end - start) / CLOCKS_PER_SEC;

    printf("Test config: begin = 0x%llx, end = 0x%llx, step = %u\n", config->begin, config->end, config->step);
    printf("Access time: %.3f seconds\n", duration);
    printf("Throughput: %.3f bytes/second\n", (double)size / duration);
}

int main() {
    // 测试不同访存模式
    test_config_t configs[] = {
        {0x10000000, 0x10100000, 1}, // step = 1
        {0x10000000, 0x10100000, 2}, // step = 2
        {0x10000000, 0x10100000, 10}, // step = 10
        {0x10000000, 0x10100000, 6 + rand() % 5}, // step = random(6, 10)
    };

    for (int i = 0; i < sizeof(configs) / sizeof(test_config_t); i++) {
        test_access(&configs[i]);
    }

    return 0;
}

说明

  • 该代码定义了一个test_config_t结构体,用于存储测试配置信息,包括起始地址、结束地址和每次读取的跨度。
  • test_access函数用于执行访问测试。它首先记录开始时间,然后循环读取数据,并记录结束时间。最后,计算访问时间、吞吐率并打印结果。
  • main函数定义了四个测试配置,并分别调用test_access函数进行测试。

如何使用

  1. 将代码保存为test.c文件。
  2. 使用GCC编译器编译代码:
gcc -o test test.c
  1. 运行测试程序:
./test

在不设置CPU主频时的执行结果

Test config: begin = 0x10000000, end = 0x10100000, step = 1
Access time: 0.097 seconds
Throughput: 1073741824.000 bytes/second
Test config: begin = 0x10000000, end = 0x10100000, step = 2
Access time: 0.049 seconds
Throughput: 2147483648.000 bytes/second
Test config: begin = 0x10000000, end = 0x10100000, step = 10
Access time: 0.010 seconds
Throughput: 1073741824.000 bytes/second
Test config: begin = 0x10000000, end = 0x10100000, step = 7
Access time: 0.070 seconds
Throughput: 1536000000.000 bytes/second

1.2 执行结果解释

  1. Test config: begin = 0x10000000, end = 0x10100000, step = 1
    • Access time : 0.097 seconds
    • Throughput : 1073741824.000 bytes/second
    • 解释 : 由于步长为1,访问模式是顺序的,缓存预取机制有效,所以访问时间较短,吞吐量较高。
  2. Test config: begin = 0x10000000, end = 0x10100000, step = 2
    • Access time : 0.049 seconds
    • Throughput : 2147483648.000 bytes/second
    • 解释 : 步长为2,访问模式仍然较为顺序,缓存预取机制仍有效,所以访问时间更短,吞吐量更高。
  3. Test config: begin = 0x10000000, end = 0x10100000, step = 10
    • Access time : 0.010 seconds
    • Throughput : 1073741824.000 bytes/second
    • 解释 : 步长为10,访问模式变得不那么顺序,缓存预取机制失效,导致访问时间更短,但吞吐量反而下降,因为在大步长情况下,CPU利用率可能较低。
  4. Test config: begin = 0x10000000, end = 0x10100000, step = 7
    • Access time : 结果未完整显示
    • 解释 : 由于步长为随机数(6到10之间),缓存预取机制可能无法生效,导致访问时间不确定,但可以预期较高的随机性会降低缓存效率,增加访问时间,降低吞吐量。

2. (设置CPU主频) ARM开发板访存性能测试

基于如上的测试方法,真实的业务线程在ARM开发板上测试访存性能

测试方法

  • 循环读写一个超大数组(总大小超过L2 cache大小),每次读取跨度为N个cache line大小。
  • 测试不同访存模式(step=1, step=2, step=10, step=random(6,9))和CPU主频(1.2GHz和0.6GHz)下的性能。
平台 \ 访存方式step=1step=2step=10step=rand(5,9)
ARM-APP0.120.10.020.02

测试结果

  • 当N=1或2时,由于cache预取机制生效,IPC(指令每周期)可以达到0.1以上。
  • 当N增加到10或随机范围时,cache预取机制失效,IPC显著降低至0.02。
  • 降低CPU主频,访存相对开销减少,CPI降低,IPC提高。
  • 访存/指令比越高,对应的IPC越低,反映了访存操作对CPU性能的影响。

结论与模拟的测试程序一致

3. (设置CPU主频) ARM-APP主要工作线程与访存频率的关系

以下线程1、线程2、线程3为实际的业务线程,代码无法贴出

线程1线程2线程3
l2d_cache_refill14846205.0023929355.0021485354.00
l2d_cache_wb4906288.007647479.006381314.00
cycles7457445631.005532393037.004712356772.00
insts5885430181.002863458124.002592726756.00
IPC0.790.520.55
访存/指令0.3%1.1%1.1%

以上数据展示了ARM-APP的三个主要工作线程与它们的访存频率和性能之间的关系。下面是对文档中各项数据的解释:

  • l2d_cache_refill:表示L2数据缓存(Data Cache)的重填(refill)次数。当处理器尝试从L2缓存中读取数据但数据不在缓存中时,就会发生缓存重填。这个值越高,说明缓存未命中的次数越多,需要从主存中读取数据的次数也越多。
  • l2d_cache_wb:表示L2数据缓存的写回(writeback)次数。当处理器修改了缓存中的数据,并且这些修改需要被写回到主存时,就会发生写回。
  • cycles:表示处理器执行的时钟周期数。这个值反映了线程执行的总时间。
  • insts(instructions):表示线程执行的指令数。这个值反映了线程的工作负荷。
  • IPC(Instructions Per Cycle):表示每个时钟周期执行的指令数,计算公式为insts / cycles。这个值越高,表示处理器的效率越高。
  • 访存/指令:表示每条指令的访存操作数,计算公式为(l2d_cache_refill + l2d_cache_wb) / insts。这个值越高,说明访存操作的频率越高。

3.1 线程1

  • L2缓存重填次数和写回次数相对较低。
  • 时钟周期数最高,但执行的指令数也是最多的。
  • IPC(0.79)相对较高,说明线程1的处理效率较高。
  • 访存/指令比率为0.3%,表示每1000条指令中大约有3次访存操作。较低的访存频率表明线程1能够更有效地利用缓存,减少了对主存的访问次数。

3.2 线程2和线程3

  • L2缓存重填次数和写回次数相对较高,表明这两个线程的访存操作更多。
  • 时钟周期数和执行的指令数较少。
  • IPC分别为0.52和0.55,说明处理效率较低。
  • 访存/指令比率为1.1%,表示每1000条指令中大约有11次访存操作。较高的访存频率表明线程2和线程3更依赖于主存访问,可能因为缓存未命中率较高,从而降低了处理效率。

3.3 本段总结

线程1的访存频率较低,表明它能够更有效地利用CPU缓存,减少了对主存的访问次数,因此处理效率较高(IPC较高)。线程2和线程3的访存频率较高,表明它们对主存访问的依赖度较高,CPU缓存未命中率较高,因此处理效率较低(IPC较低)。访存操作对CPU性能有显著影响,频繁的访存操作会导致处理器的效率降低。

4 总结

通过分析不同访存模式下的性能数据,可以得出以下结论,对于我测试的Cortex-A53 ARM开发板:

  1. Cache预取的影响
  • 当访问模式较为顺序(step=1,2)时,cache预取机制生效,访存效率较高,IPC较高。
  • 当访问模式较为随机(step=10, rand)时,cache预取机制失效,访存效率较低,IPC较低。
  1. CPU主频的影响
  • 降低CPU主频会减小访存操作的相对开销,从而提高IPC。
  • 低主频下的访存操作对性能的影响相对较小。
  1. 访存/指令比率的影响
  • 访存/指令比率越高,IPC越低,反映了访存操作对CPU性能的负面影响。
  • 优化访存操作(例如通过数据局部性优化)可以显著提高CPU性能。

综合本次测试和分析,我们可以得出以下结论:

  • 访存性能对ARM开发板CPU性能有显著影响。
  • 合理优化访存模式和利用cache预取机制可以提高CPU性能。
  • 降低CPU主频可以减小访存操作的相对开销,从而提高CPU效率。
  • 进一步的优化可以通过减少访存操作频率和优化数据局部性来实现。

在实际应用中,针对特定场景进行访存模式优化,选择合适的CPU主频,可以显著提升系统的整体性能。因此,若想充分发挥高主频CPU的优势,足够大的CPU缓存也是有必要的。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘色的喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值