乍看之下,让硬盘自行写入RAM似乎是个好主意,而无需CPU指令复制数据,尤其是考虑到异步网络的成功。但是直接内存访问(DMA)上的Wikipedia article指出:
我不明白如何才能“部分封锁”公交线路。大概一次只能由一台设备访问内存,然后看来CPU实际上无法执行任何有用的工作。在第一次尝试读取未缓存的内存时,它将被阻止,我预计在2 mb缓存的情况下会很快。
释放CPU来执行其他任务的目标似乎是没有根据的。硬盘DMA在实践中是否有助于提高性能?
最佳答案
1:PIO(编程的IO)会破坏CPU缓存。从磁盘读取的数据在大多数情况下不会在之后立即处理。应用程序通常以大块读取数据,但PIO以较小的块(通常为64K IIRC)完成。因此,数据读取应用程序将等到大块传输完毕后再使用,而从 Controller 中获取的较小块就不会从高速缓存中受益。同时,其他应用程序将遭受高速缓存的大部分被传输驱逐的痛苦。可以通过使用特殊的指令来避免这种情况,这些指令会指示CPU不要缓存数据,而是将其“直接”写入主内存,但是我很确定这样做会减慢复制循环的速度。因此,造成的伤害甚至超过了缓存破坏。
2:由于PIO是在x86系统以及可能在大多数其他系统上实现的,因此与DMA相比,它的运行速度确实很慢。问题不在于CPU不够快。问题源于总线和磁盘 Controller 的PIO模式的设计方式。如果我没记错的话,CPU必须从所谓的IO端口读取每个字节(或使用32位PIO模式时的每个DWORD)。这意味着对于每个DWORD数据,端口地址都必须放在总线上,并且 Controller 必须通过将数据DWORD放在总线上来做出响应。而使用DMA时, Controller 可以利用总线和/或存储器 Controller 的全部带宽来传输数据突发。当然,有很多空间可以优化此传统PIO设计。 DMA传输就是这样的优化。仍然可以考虑将其他解决方案视为PIO的方法也是可能的,但是同样,它们仍将遭受其他问题的困扰(例如,上面提到的缓存颠簸)。
3:存储器和/或总线带宽不是大多数应用的限制因素,因此DMA传输不会停止任何事情。这可能会使某些应用程序变慢一些,但通常应该不怎么引起注意。毕竟,与总线和/或内存 Controller 的带宽相比,所有磁盘都相当慢。速度大于500 MB/s的“磁盘”(SSD,RAID阵列)确实非常快。总线或内存子系统至少不能提供该数字的10倍必须是从石器时代开始的。 OTOH PIO在传输数据块时确实使CPU完全停顿。