CPU: 英特尔 Sandy / Ivy Bridge (x86_64)
我需要编写一个设备驱动程序,通过PCI Express连接到CPU,并需要使用最大带宽。为此,我将映射的设备内存映射到处理器的物理地址空间中。然后使用 ioremap_wc ()
将该内存映射到内核的虚拟地址空间中,并标记为 WC(写组合)。
众所周知,在x86_64 CPU中有几个缓冲区:
- Cache - 一个著名的快速内存缓冲区,由三个缓冲区组成:L1 / L2 / L3。每个级别都由64字节的缓存行组成。
- 在 WB(写回)模式下 - (异步)在后台CPU使用任意顺序的64字节块将数据从缓存写入RAM。
- 在 WT(写穿透)模式下 - (同步)使用
MOV [addr],reg
将每个存储到内存的缓存行立即存储到缓存和RAM中。
关于缓存级别的详细信息:每个核心都有L1(64 KB,1 ns)和L2(256 KB,3 ns),而整个CPU对所有核心都有一个缓冲区L3(4-40 MB,10 ns)。
(SB)存储缓冲区 - 一个缓冲区(队列),其中所有数据按顺序存储。并且以相同的顺序在后台懒惰地将数据存储到内存中。但是可以使用
SFENCE
或MFENCE
强制将数据从存储缓冲区保存到 Cache / RAM 中(例如支持核之间的顺序一致性)。BIU(总线接口单元)/ WCB(写组合缓冲区) - 在 WC(写组合)模式下。当将内存区域标记为WT时,不使用缓存,而使用大小为64字节的BIU / WCB作为缓存行。当我们通过1字节64次存储到内存
MOV [addr],reg
时,仅当最后一个字节已存储时,整个 BIU / WCB 才会存储到内存中 - 这是用于通过整个64字节块向内存区域写入数据的优化机制。例如,这是将数据存储到通过PCI-Express接口映射到CPU物理地址空间的设备内存中的非常重要的机制,其中通过64字节的记录(发送)将实际带宽增加了数倍。但是可以使用SFENCE
或MFENCE
强制将数据从 BIU / WCB 保存到 [远程] 内存中。
还有一些相关问题:
1. 缓存、存储缓冲区和BIU / WCB是否都使用CPU中相同的物理缓冲区,但是它们的不同部分,或者它们都有单独的物理缓冲区?
2. 如果缓存和BIU使用相同的物理缓冲区,例如都使用Cache-L1的某些部分,则为什么SFENCE / MFENCE
对第二个有影响,而对第一个没有影响。如果它们有单独的物理缓冲区,那么为什么Cache-line和BIU的大小都是64字节?
3. L1缓存的缓存行数为(65536/64)= 1024,L2缓存为(262144/64)= 4096,L3缓存为4 MB / 64字节。我们不知道Store Buffer的大小。但是单个CPU核心或整个CPU上有多少个BUIs / WCBs(每个64字节)?
4. 如我们所见,命令SFENCE
或MFENCE
会影响存储缓冲区和BIU / WCB。但是这些命令是否会对缓存(L1 / L2 / L3)产生任何影响?