cache(二)直接缓存映射-4. 代码

在这里插入图片描述
这个图展示了在缓存中访问二维数组的两种不同方式对性能的影响。通过 sum_array_rowssum_array_cols 两种函数,展示了按行访问和按列访问的区别。

缓存的假设配置

  • 每个缓存组包含一个块(One block per set)。
  • 每个块可以存储 8 个 double 类型的数据(即 64 字节,因为一个 double 占用 8 字节)。
  • 初始状态为冷缓存(cold cache),即缓存是空的。

函数分析

  1. sum_array_rows 函数(按行访问)

    int sum_array_rows(double a[16][16]) {
        int i, j;
        double sum = 0;
        for (i = 0; i < 16; i++)
            for (j = 0; j < 16; j++)
                sum += a[i][j];
        return sum;
    }
    
    • 访问模式:按行访问,即 a[i][j],对于每个 ij 从 0 到 15 遍历。这意味着程序会连续访问数组的一行内的元素。
    • 缓存效果:由于每个块可以存储 8 个 double,当访问 a[i][0] 时,a[i][0]a[i][7] 会被加载到同一个缓存块中。
      • 当访问到 a[i][1]a[i][7] 时,数据已经在缓存中,命中率较高。
      • 然后访问 a[i][8] 时,会加载 a[i][8]a[i][15],这段访问也会命中。
    • 结果:按行访问时,缓存命中率较高,效率较高。
  2. sum_array_cols 函数(按列访问)

    int sum_array_cols(double a[16][16]) {
        int i, j;
        double sum = 0;
        for (j = 0; j < 16; j++)
            for (i = 0; i < 16; i++)
                sum += a[i][j];
        return sum;
    }
    
    • 访问模式:按列访问,即 a[i][j],对于每个 ji 从 0 到 15 遍历。这意味着程序会在一列内访问元素。
    • 缓存效果:由于每次访问时跳到下一行的元素,a[i][j]a[i+1][j] 不在同一个缓存块中。
      • 每次访问会导致缓存未命中,因为 a[i][j]a[i+1][j] 属于不同的块。
    • 结果:按列访问时,缓存命中率低,效率较差。

总结

  • 按行访问sum_array_rows)会充分利用缓存,使连续的数据加载到同一个缓存块中,从而提高缓存命中率。
  • 按列访问sum_array_cols)导致缓存不命中频繁发生,因为每次访问跳到不同的块,无法充分利用缓存。
  • 因此,二维数组的访问方式对缓存命中率有显著影响。通常情况下,按行访问效率更高,特别是在直接映射缓存或低相联度缓存中。
上一篇:.普通铜导线、漆包线、普通电线能代替绕线电阻材料吗


下一篇:vue中的keep-alive是什么,有哪些使用场景,使用了什么原理,缓存后如何更新数据