首页 文章

Intel Xeon CPU如何写入内存?

提问于
浏览
26

我正在尝试在两种算法之间做出决定 . 一个写入8个字节(两个对齐的4字节字)到2个高速缓存行,另一个写入3个整个高速缓存行 .

如果CPU仅将更改的8个字节写回内存,则第一个算法使用的内存带宽要少得多:8个字节对192个字节 . 如果CPU写入整个高速缓存行,则128和192字节之间的差异不那么显着 .

那么Intel Xeon CPU如何写回内存?你会惊讶地发现在谷歌找到一个应该众所周知的答案是多么困难 .

据我所知,写入进入存储缓冲区,然后进入缓存 . 当脏缓存行从缓存中逐出时,它们可能只被写入内存,但是英特尔是否跟踪缓存行的哪些部分是脏的,或者只是转储整个内容?我更怀疑他们跟踪缓存行粒度以下的事情 . 如果在高速缓存行被驱逐之前有任何内容进入内存,我也会感到非常惊讶 .

2 回答

  • 17

    即使对于DRAM本身来说,局部性也很重要,甚至可以忽略缓存 . 对于脏缓存行,64B连续字节的突发写入比4B到16个不同地址的16次写入快得多 . 或者换句话说,写回整个缓存行并不比写回缓存行中的几个更改字节慢得多 .

    由Ulrich Drepper撰写的What Every Programmer Should Know About Memory解释了许多关于在编程时避免内存瓶颈的问题 . 他介绍了DRAM寻址的一些细节 . DRAM控制器必须选择一行,然后选择一列 . 访问另一个虚拟内存页面也会导致TLB未命中 .

    DRAM确实具有用于传输顺序数据块的突发传输命令 . (显然是为了回写缓存行的CPU而设计的) . 现代计算机中的存储器系统针对编写整个高速缓存行的使用模式进行了优化,因为这几乎总是发生 .

    缓存行是CPU跟踪脏或不跟踪的单位 . 可以使用比现有或未高速缓存行更小的线路大小来跟踪脏度,但是这将需要额外的晶体管并且不值得 . 设置多级缓存以传输整个缓存行,因此当需要读取整个缓存行时,它们可以尽可能快 .

    存在绕过缓存的所谓非时间读/写( movnti/movntdqa ) . 这些用于与一次8B写入相同的数据 . )

    只接触两个缓存行的算法肯定在该分数上具有优势,除非需要更多的计算,或者特别是分支,以确定要写入哪个内存 . 如果你想要帮助决定,也许会问一个不同的问题 . (请参阅https://stackoverflow.com/tags/x86/info的链接,esp Agner Fog的指南,了解有助于您自己决定的信息 . )

    请参阅Cornstalks的回答,了解有关在不同CPU上触摸同一内存时有多个线程的危险的警告 . 这可能导致比单线程程序的额外写入更大的减速 .

  • 8

    为了使CPU只将脏字节写回内存,需要为缓存中的每个字节存储一个脏位 . 这是不可行的,并没有在现代CPU上完成(据我所知) . CPU只有一个脏位用于缓存行 . 写入高速缓存行中的任何字节都会导致整行被标记为脏 .

    当需要刷新脏缓存行时,需要写入整行,因为CPU不知道哪个字节发生了变化 .

    这可以在高速缓存失效策略中看出,其中写入核心中的一个高速缓存行可以使不同核心中的高速缓存行无效(因为两个高速缓存行映射到相同的地址),即使第一个核心正在使用lo-高速缓存行的一半和第二个核心使用高速缓存行的一半 . 也就是说,如果核心1写入字节N,核心2使用字节N 1,则核心2仍然必须刷新其缓存行,即使您和我知道它没有必要 .

相关问题