【问题标题】:Finding the Cache Miss/Hit Rate in Multi-Dimensional Arrays查找多维数组中的缓存未命中/命中率
【发布时间】:2013-12-13 04:20:39
【问题描述】:

我正在尝试学习测试,其中一个练习问题涉及计算缓存的“命中”和“未命中”率。我有这个问题的答案,但我无法弄清楚它背后的过程。

鉴于以下情况;

具有 32 字节块的 2048 字节直接映射数据缓存。 并假设 sizeof(int) == 4,Square 从内存地址 0 开始, 缓存最初是空的,变量 i 和 j 存储在寄存器中。

  struct point_color { 
  int c; 
  int m; 
  int y; 
  int k; 
  }; 

  struct point_color square[16][16]; 
  int i, j;

  for (i = 0; i < 16; i++){ 
  for (j = 0; j < 16; j++) { 
  square[i][j].c = 0; 
  square[i][j].m = 0; 
  square[i][j].y = 1; 
  square[i][j].k = 0; 
  } 
  } 

我正在尝试查找“缓存中未命中的写入总数”和“未命中率”

到目前为止,我知道写入的总数是 16*16*4 = 1024 次,但是在尝试查找缓存命中率和未命中率时我完全迷失了。

【问题讨论】:

  • 第一次写入时,什么被带入缓存?

标签: arrays caching matrix-multiplication


【解决方案1】:

具有 32 字节块的 2048 字节直接映射数据缓存。并假设 sizeof(int) == 4,Square 从内存地址 0 开始,缓存最初是空的,变量 i 和 j 存储在寄存器中。

您可以将struct point_color square[16][16]; 视为内存中从 0 开始的长磁带。矩阵中的每个条目都包含一个大小为 4*4 = 16 字节的结构。当矩阵完全被结构填充时,它的大小将是 16*16*16 = 4096 字节。 (内存地址 0...4095-16),看起来像这样(右侧的内存地址):

+-----------------+
|  square[0][0]   | 0-15
+-----------------+
|  square[0][1]   | 16-31
+-----------------+
|  square[0][2]   | 32-47
+-----------------+
        .
        .
        .
+-----------------+
|  square[15][15] | 4080-4095
+-----------------+

缓存直接映射为 32 字节块,这意味着它看起来像这样:

  +----------------+
  |    32 bytes    | row 0   
  +----------------+          
  |    32 bytes    | row 1    
  +----------------+          
  |    32 bytes    | row 2    
  +----------------+          
          .                   
          .                   
          .                   
  +----------------+          
  |    32 bytes    | row 63   
  +----------------+       

如您所见,写入的前 2048 个字节将全部放入缓存中,之后缓存将需要开始替换缓存中的行。由于这是一个直接映射的缓存,因此替换是直截了当的。您可以通过查看内存地址并将其分成几部分来计算内存块应放置在缓存中的哪一行。对于这个特定的缓存,地址布局是:

   +----------------------+----------+--------+
   |       21bits         | 6bits    | 5bits  |
   |        tag           | index    | offset |
   +----------------------+----------+--------+

操作顺序和缓存命中/未命中如下所示:

write square[0][0].c = 0;   ---> cache miss (address 0), load memory block 0-31 into cache
write square[0][0].m = 0;   ---> cache hit (address 4)
write square[0][0].y = 0;   ---> cache hit (address 8)
write square[0][0].k = 0;   ---> cache hit (address 12)
write square[0][1].c = 0;   ---> cache hit (address 16)
write square[0][1].m = 0;   ---> cache hit (address 20)
write square[0][1].y = 0;   ---> cache hit (address 24)
write square[0][1].k = 0;   ---> cache hit (address 28)
write square[0][2].c = 0;   ---> cache miss (address 32), load memory block 32-63 into cache
write square[0][2].m = 0;   ---> cache hit (address 36)
write square[0][2].y = 0;   ---> cache hit (address 40)
                             .
                             .
                             .
                             .
write square[8][0].c = 0;   ---> cache miss (address 2048), load memory block 2048-2079 into cache and replace the cache-row containing memory block 0-31
write square[8][0].m = 0;   ---> cache hit (address 2052)
write square[0][0].y = 0;   ---> cache hit (address 2056)
                             .
                             .
                             .

你看到模式了吗? 1/8 操作将是缓存未命中。

未命中率: 12.5%

命中率: 87.5%

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-04
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多