写入组合:在写入之前避免读取哪个高速缓存行?

时间:2013-03-22 19:14:56

标签: caching memory x86-64 intrinsics

关于非时间写入和写入组合技术,我有以下代码

void setbytes(char *p, int c)
{
__m128i i = _mm_set_epi8(c, c, c, c,
c, c, c, c,
c, c, c, c,
c, c, c, c);
_mm_stream_si128((__m128i *)&p[0], i);
_mm_stream_si128((__m128i *)&p[16], i);
_mm_stream_si128((__m128i *)&p[32], i);
_mm_stream_si128((__m128i *)&p[48], i);
}

取自here

写的是

  

总而言之,此代码序列不仅避免了读取缓存   在写入之前的行,它也避免了用于污染缓存   可能不会很快需要的数据。这可以带来巨大的好处   某些情况。

我的问题是:避免写入哪个缓存行?存储i变量内容的缓存行或p指针所指向的缓存行(之后会被修改)?

2 个答案:

答案 0 :(得分:3)

about:“避免在写入之前读取缓存行”

此语句引用“写入分配”策略来处理错过缓存的写入。所有现代x86处理器都是这样做的。它是这样的:软件使用普通的mov指令写入内存。如果该地址已被缓存,则更新缓存并且根本没有DRAM访问。但是,如果数据不在缓存中,则处理器从DRAM读取该缓存行。然后将来自mov指令的数据合并到缓存中的数据中。处理器将推迟尽可能长时间地将数据写回DRAM。最终结果是违反直觉的:软件执行写(mov)指令,并产生单个DRAM读(突发)结果。如果重复此模式,缓存最终将变满,并且需要驱逐以为读取腾出空间。在这种情况下,将存在无关高速缓存行地址的DRAM写突发,然后读取软件正在写入的地址。这解释了为什么非临时存储为填充大缓冲区提供了大约2倍的性能。与使用mov填充缓冲区相比,只有一半的DRAM访问次数出现。

答案 1 :(得分:1)

如果目标地址不在缓存中,则流可以防止污染缓存,否则只需根据需要更新缓存,新值写入该缓存行支持的地址。

所以在你的例子中,如果你没有从p读取(或者你用CLFLUSH从缓存刷新了它),流式存储将阻止数据写入{{1}被加载到p指向的地址的缓存中的点(即:将不会为写入的地址创建cachline)。