我正在阅读Ulrich Drepper 的每个程序员应该了解的关于内存的知识 pdf。在第 6 部分的开头有一段代码:
#include <emmintrin.h>
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);
}
在它下面有这样的评论:
假设指针
p
正确对齐,调用此函数会将寻址缓存行的所有字节设置为c
. 写组合逻辑将看到四个生成的 movntdq 指令,并且仅在执行完最后一条指令后才向内存发出写命令。总而言之,这个代码序列不仅避免了在写入之前读取缓存行,还避免了可能很快不需要的数据污染缓存。
让我感到困扰的是,在对函数的注释中写道,它“会将寻址缓存行的所有字节设置为 c”,但根据我对流内部结构的理解,它们绕过缓存 - 既没有缓存读取也没有缓存写入。此代码将如何访问任何缓存行?第二个粗体片段表示类似,该函数“避免在写入之前读取缓存行”。如上所述,我看不到任何缓存的写入方式和时间。此外,是否需要在缓存写入之前对缓存进行任何写入?有人可以向我澄清这个问题吗?