【问题标题】:Latency measurement of each level of memory hierarchy每个内存层次结构的延迟测量
【发布时间】:2014-11-15 21:45:33
【问题描述】:

我想测量每个内存层次结构级别的延迟,从 L1 到主内存。所以,我试图了解https://gist.github.com/jiewmeng/3787223 的1-single.c 程序。为什么数组的索引是由 [(i * 16) & lengthMod] 计算的?

[(i * 16) & lengthMod] 和 i*16 的值总是相同的。例如,

i=0, [(i * 16) & lengthMod]=0, [i*16]=0
i=1, [(i * 16) & lengthMod]=16, [i*16]=16
i=2, [(i * 16) & lengthMod]=32, [i*16]=32
i=3, [(i * 16) & lengthMod]=48, [i*16]=48
i=4, [(i * 16) & lengthMod]=64, [i*16]=64
i=5, [(i * 16) & lengthMod]=80, [i*16]=80
.........................................

所以,我尝试运行将 [(i * 16) & lengthMod] 替换为 [i * 16] 的程序,但是程序每次都崩溃。这就是我意识到这种按位操作背后一定有充分理由的原因。谁能解释一下为什么数组是由 [(i * 16) & lengthMod] 计算的?

【问题讨论】:

    标签: c caching bit-manipulation latency


    【解决方案1】:

    for 循环中:

    for (i = 0; i < steps; i++) {
        arr[(i * 16) & lengthMod] *= 10;
    

    steps 是 256 MB,arr[] 有 4 MB 的元素。因此,如果您将数组访问权限更改为arr[i * 16],您将很快溢出数组并进入未定义的行为领域。

    在你的原始代码中:

    lengthMod = sizes[s] - 1;
    

    其中sizes[] 被定义为容纳2 到4MB 的各种幂。因此,当您执行(i * 16) &amp; lengthMod 时,您确保数组访问永远不会等于或超过sizes[s],从而防止发生数组溢出。

    【讨论】:

      【解决方案2】:

      在最近的大多数处理器中,缓存行大小为 64B

      数组元素索引为 0,1,2... 一个元素 4B 缓存线大小 / 一个元素大小 = 64/4 =16

      每个缓存行有 16 个元素 (=> 64B) 所以它就像缓存行 0 中的数组 0 到 15 个元素 缓存行 1 中的 16 到 31 个元素 缓存行 2 中的 32 到 47 个元素 ...

      如果您访问任何元素,则该元素的缓存行将被带入内存。

      所以访问第 0 个元素会将 cacheline0 带入缓存 访问第 16 个元素会将下一个缓存 line1 带入缓存。

      你不需要访问所有元素;您只需要访问缓存行的一个元素即可带来所有其他 15 个元素!

      这就是你看到那里的原因 *16

      【讨论】:

        猜你喜欢
        • 2012-01-28
        • 2012-01-17
        • 2015-08-14
        • 2021-06-13
        • 2014-02-17
        • 2019-11-19
        • 1970-01-01
        • 2015-03-24
        • 1970-01-01
        相关资源
        最近更新 更多