Language agnostic 冗余写操作上的缓存行为

Language agnostic 冗余写操作上的缓存行为,language-agnostic,optimization,caching,computer-architecture,Language Agnostic,Optimization,Caching,Computer Architecture,编辑-我想我问的问题太长了,所以我把它说得很具体 问题:如果内存位置在一级缓存中且未标记为脏。假设它有一个值X。如果您尝试将X写入同一位置,会发生什么?有没有CPU会发现这样的写入是多余的并跳过它 例如,是否有一种优化方法比较这两个值并丢弃对主内存的冗余写回?具体来说,主流处理器如何处理这个问题?如果该值是一个特殊值(如0),该怎么办?如果即使对于像0这样的特殊值也没有这样的优化,有什么原因吗 动机:我们有一个可以轻松放入缓存的缓冲区。多个线程可能通过在它们之间循环使用它。每次使用都涉及写入缓冲

编辑-我想我问的问题太长了,所以我把它说得很具体

问题:如果内存位置在一级缓存中且未标记为脏。假设它有一个值X。如果您尝试将X写入同一位置,会发生什么?有没有CPU会发现这样的写入是多余的并跳过它

例如,是否有一种优化方法比较这两个值并丢弃对主内存的冗余写回?具体来说,主流处理器如何处理这个问题?如果该值是一个特殊值(如0),该怎么办?如果即使对于像0这样的特殊值也没有这样的优化,有什么原因吗

动机:我们有一个可以轻松放入缓存的缓冲区。多个线程可能通过在它们之间循环使用它。每次使用都涉及写入缓冲区中的n位置(不一定是连续的)。循环只是意味着将所有值设置为0。每次我们回收时,size-n位置已经为0。在我看来(凭直觉)避免如此多的冗余回写会使回收过程更快,因此问题就来了

在代码中这样做没有意义,因为分支指令本身可能会导致不必要的缓存丢失(if(buf[i]){…})

这不是对您最初关于计算机体系结构问题的回答,但可能与您的目标有关

在本讨论中,所有数组索引都以零开始


假设nsize小得多,请更改算法,使其保存两条信息:

  • 大小为的数组
  • 一个n数组和一个计数器,用于模拟集合容器。允许重复值
  • 每次向全尺寸数组中的索引k写入非零值时,将值k插入集合容器

    当需要清除全尺寸数组时,获取set容器中存储的每个值(其中将包含k),并将全尺寸数组中的每个对应索引设置为零


    也可以使用类似的技术,称为两级直方图或基数直方图

    存储两条信息:

  • 大小为
    的数组
  • ceil(size/M)
    的布尔数组,其中
    M
    是基数
    ceil
    是天花板功能
  • 每次向全尺寸数组中的索引k写入非零值时,应标记布尔数组中的元素
    floor(k/M)

    比如说,
    bool\u数组[j]
    被标记。这对应于全尺寸阵列中从
    j*M
    (j+1)*M-1
    的范围


    当需要清除全尺寸数组时,请扫描布尔数组中的任何标记元素,并应清除全尺寸数组中相应的范围。

    您建议的硬件优化不会减少延迟。考虑最低级别的操作:

  • 该位置的旧值从缓存加载到CPU(假设它已经在缓存中)
  • 比较新旧值
  • 如果新旧值不同,则新值将写入缓存。否则它将被忽略
  • 步骤1实际上可能比步骤2和3花费更长的时间。这是因为在将步骤1中的旧值引入CPU之前,步骤2和3无法启动。如果在软件中实现,情况也是一样的

    考虑一下我们是否只是将新值写入缓存,而不检查旧值。它实际上比上面提到的三步流程要快,原因有二。首先,不需要等待旧值。其次,CPU可以简单地在输出缓冲区中安排写操作。输出缓冲区可以同时执行缓存写入,而ALU可以开始处理其他内容

    到目前为止,唯一涉及的延迟是CPU和缓存之间的延迟,而不是缓存和主内存之间的延迟


    在现代微处理器中,情况更为复杂,因为它们的缓存被组织成缓存线。当字节值写入缓存线时,必须加载完整的缓存线,因为未重写的缓存线的其他部分必须保留其旧值

    阅读 缓存命中:数据从缓存线读取到目标寄存器
  • 缓存未命中:数据从内存移动到缓存,并读取到目标寄存器中
  • 写 缓存命中:数据从寄存器移动到缓存线
  • 缓存未命中:缓存线被提取到缓存中,并且来自寄存器的数据被移动到缓存线

  • 我不知道有哪个处理器会像你描述的那样进行优化——消除对干净缓存线的写操作,这不会改变值——但这是一个好问题,一个好主意,伟人的想法都是一样的

    我写了一个很好的回复,然后我想起了:这在文学中被称为“无声商店”。见“免费无声商店”,K.Lepak和M Lipasti,UWisc,MICRO-332000

    无论如何,在我的回复中,我描述了一些实现问题

    顺便说一下,像这样的话题经常在USEnet新闻组comp.arch中讨论


    我也在我的维基上写了关于它们的文章,

    这是一个非常大的问题,高度依赖于体系结构。下面是一篇英特尔应用程序说明,内容可能与您的任务有关,或者至少有助于您更好地阐述问题:我认为这篇文章没有回答我的问题。我读过很多关于缓存的文章,但没有一篇是关于我的