hen*_*nle 7 memory io cpu system blocking
乍一看似乎是一个好主意让硬盘自己写入RAM,没有CPU指令复制数据,特别是考虑到异步网络的成功.但维基百科关于直接内存访问(DMA)的文章指出:
使用DMA,CPU可以从这种开销中解脱出来,并且可以在数据传输期间执行有用的任务(尽管CPU总线会被DMA 部分阻止).
我不明白公交线路是如何"部分阻挡"的.据推测,当时一个设备可以访问内存,然后看起来CPU实际上没有什么有用的工作.它会在第一次尝试读取未缓存的内存时被阻止,我预计在2 mb缓存的情况下会非常快.
释放CPU来执行其他任务的目标似乎是无偿的.硬盘DMA是否会在实践中促进任何性能提升?
1:PIO(编程IO)使CPU缓存崩溃.大多数情况下,从磁盘读取的数据不会立即处理.应用程序通常以大块读取数据,但PIO以较小的块(通常为64K IIRC)完成.因此,数据读取应用程序将等待直到大块已经传输,并且在从控制器取出之后不会从缓存中的较小块中受益.同时,其他应用程序将受到传输驱逐的大部分缓存的影响.这可以通过使用特殊指令来避免,这些指令指示CPU不要缓存数据,而是"直接"将其写入主存储器,但是我很确定这会降低复制循环的速度.因此,甚至比缓存捶打更痛苦.
2:PIO,因为它在x86系统上实现,可能是大多数其他系统,与DMA相比真的很慢.问题不在于CPU不够快.问题源于总线和磁盘控制器的PIO模式的设计方式.如果我没弄错的话,CPU必须从所谓的IO端口读取每个字节(或使用32位PIO模式时的每个DWORD).这意味着对于每个DWORD数据,端口的地址必须放在总线上,控制器必须通过将数据DWORD放在总线上来响应.然而,当使用DMA时,控制器可以利用总线和/或存储器控制器的全部带宽来传输突发数据.当然,优化这种传统PIO设计还有很大的空间.DMA传输就是这样的优化.
3:内存和/或总线带宽不是大多数应用程序的限制因素,因此DMA传输不会停止任何操作.它可能会减慢一些应用程序的速度,但通常它几乎不会引起注意.在所有磁盘与总线和/或存储器控制器的带宽相比相当慢之后.提供> 500 MB/s的"磁盘"(SSD,RAID阵列)非常快.总线或内存子系统至少不能提供10倍的数量,必须来自石器时代.OTOH PIO在传输数据块时完全停止了CPU.
我不知道我是否遗漏了什么.
我们假设我们没有DMA控制器.从"慢"设备到内存的每次传输都是CPU的循环
ask_for_a_block_to_device
wait_until_device_answer (or change_task_and_be_interrupted_when_ready)
write_to_memory
Run Code Online (Sandbox Code Playgroud)
所以CPU应该自己写内存.块大块.
是否有必要使用CPU进行内存传输?不.我们使用另一种设备(或像DMA总线主控那样的机制)将数据传输到存储器或从存储器传输数据.
与此同时,CPU可以做一些不同的事情:用缓存做事,甚至在很大一部分时间内访问内存的其他部分.
这是至关重要的部分:数据不会在100%的时间内被传输,因为其他设备非常慢(与内存和CPU相比).
试图表示共享内存总线使用的示例(当CPU接收时,C,当被DMA接收时为C)
Memory Bus ----CCCCCCCC---D----CCCCCCCCCDCCCCCCCCC----D
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,内存一次只能加入一个设备.有时由CPU,有时由DMA控制器.DMA很少次.