memory type

Memory Type

什么是Memory Type

每个内存区域都有自己的memory type,代表此内存区域的一些特性,例如数据是否会使用cache、访存操作是否可以reorder等等

Linux下可以通过以下命令查看

1
cat /sys/kernel/debug/x86/pat_memtype_list

目前IA32中的memory type如下表所示

Memory Type and Mnemonic read cacheable write cacheable read allocate write allocate Allows Speculative Reads Memory Ordering Model
Strong Uncacheable(UC) No No No No No Strong Ordering
Uncacheable (UC-) No No No No No Strong Ordering. Can only be selected through the PAT. Can be overridden by WC in MTRRs.
Write Combining (WC) No No No No Yes Weak Ordering. Available by programming MTRRs or by selecting it through the PAT.
Write-through (WT) Yes Yes Yes No Yes Speculative Processor Ordering
Write Back(WB) Yes Yes Yes Yes Yes Speculative Processor Ordering
Write protected(WP) Yes No Yes No Yes Speculative Processor Ordering. Available by programming MTRRs.
  • Strong Uncacheable(UC) : 对于UC的内存读写操作都不会写到cache里,不会被reordering。

    • 对于memory-mapped I/O device,UC很适用。SMP 系统上,各个 CPU 可以通过支持 cache 一致性协议的总线 snoop 到其他 CPU 对 cache 的读写,而通过 PCIe 连接的 CPU 和 GPU 则不能互相 snoop,如图一所示,因此从 CPU 的角度,显存算是 I/O memory,对其访问需要是 uncachable 的(注1)。reordering也会导致I/O device读到dirty data,比如说I/O device把这些内存作为一些控制用的寄存器使用。

      cpu_gpu_access对于普通用途的内存,UC会导致性能的急剧下降。

    注1: 一种例外是,有些I/O device支持bus coherency protocol,可以和CPU保持cache一致性,这样的话是可以使用cacheable的内存的,但是这种总线协议也是有代价的。

  • Uncacheable (UC-): 和UC类型一样,除了UC- memory type可以通过设置MTRRs被改写为WC memory type.

  • Write Combining (WC): 文档,WC内存不会被cache,bus coherency protcol不会保证WC内存的读写。在WC类型的内存上的写操作会被延迟,数据会在cpu的WC buffer上被组合,这样可以减少总线上的访存操作。对同一地址的连续写,以最后一次写入的为准。

    显存作为 frame buffer 有个特点,就是它容许对不同地址写操作的 combine 和 reorder(写入不同像素点的数据往往是不相关的),这和普通的 MMIO 是不同的,因此就有了 WC 这种相对特殊的类型

    注2: Speculative read是指读之前并不验证内存的有效性,先冒险的读进来,如果发现不是有效数据再取消读取操作,并更新内存后再读取. 比如说数据还是被buffer在WC buffer中

  • Write back(WB):read 和 write 都 cache,在read 或者write miss时,都会同步写入数据到cache中

  • Write Through(WT):read 时 cache,write hit 时同步写入 cache line 和 main memory,而 write miss 时不分配 cache line(即没有 write allocate),直接写入 memory

  • Write protected(WP): 读操作和WT/WB没有什么区别,读会被cache. 写不一样,写的时候会在bus上传播这个操作,并且导致其他处理器上的cache lines被更新。主要用于多处理器的情况。WP的内存,在写的时候就会更新其他处理器上的cache,而WB/WT类型的内存需要等到其他处理读的时候才会去更形无效的cache

上述几种内存属性中,WB理论上性能最好,因为既不会使用cache,又可以reordering

memory_reorder

可以得知,cache和out-of-order并不是两个独立的特性,memory type将他们交织在了一起

prefetch

1
_mm_prefetch(char const* p, int i);

从地址P处预取尺寸为cache line大小的数据缓存,参数i指示预取方式(_MM_HINT_T0, _MM_HINT_T1, _MM_HINT_T2, _MM_HINT_NTA,分别表示不同的预取方式)

  • T0 预取数据到所有级别的缓存,包括L0
  • T1 预取数据到除L0外所有级别的缓存
  • T2 预取数据到除L0和L1外所有级别的缓存
  • NTA 预取数据到非临时缓冲结构中,可以最小化对缓存的污染

NTA:non-temporal aligned,程序告诉处理器应该尽可能地避免以这个数据污染cache,因为数据只在一段很短的期间内会被使用

non-temporal的含义

  • 将数据放入cache,但假设只使用一次。通常的实现方法是加载数据,但偏置 “最近最少使用 “位,这样新加载的行将被视为 “最近最少使用”,而不是默认的 “最近使用”。 PREFETCHNTA 指令似乎就是这样做的。 PREFETCHNTA 还会将数据拉入 L1 数据缓存(因此在被逐出时,不必被放入到 L2 或者更高层次的缓存中),但不会将数据放入到 L2 或 L3。
  • 不将数据放在cache中,而是将其放在单独的cacheline大小的缓冲区,即WC Buffer中,以允许多次连续(部分cacheline)加载。 这就是 MOVNTDQA 和 VMOVNTDQA 指令的作用。 它们用于WC内存类型。

因此

  • 在system memory中时,memory type一般不是WC,NT的作用是将数据尽可能快地从cache中逐出
  • 在属性为WC的内存中,NT的作用是使用cpu的internal wirte buffer,不将数据放入到cache中。

memory type
http://example.com/memory-type/
作者
Yw
发布于
2024年3月4日
许可协议