1
cc930415 2017-09-11 15:59:45 +08:00
|
2
xenme 2017-09-11 18:24:36 +08:00 via iPhone
直接读写就是需要经过中转。内存映射文件就是跳过了内核,不需要再次复制
|
3
misaka20038numbe 2017-09-11 18:37:42 +08:00
就像你家的院子,只要知道地址,谁都可以来。
|
4
kaiser1992 OP @xenme windows 中直接读写 IO 也需要复制?
|
5
kaiser1992 OP @misaka20038numbe 这是进程之间实现通信的一种方式
|
6
firemiles 2017-09-11 19:07:04 +08:00
@kaiser1992 内核态数据传到用户态都需要复制吧,除非映射
|
7
kaiser1992 OP @firemiles windows 中也需要?
|
8
stephen9357 2017-09-11 21:43:17 +08:00
不需要,只要把同样物理地址再映射一份到用户态地址空间就可以了。参考 DO_DIRECT_IO 和 MDL。
|
9
kaiser1992 OP @stephen9357 windows 中的普通 IO 有从内核空间到用户空间复制数据这个过程吗?
|
10
xenme 2017-09-11 22:44:13 +08:00 via iPhone
@kaiser1992 一般 io 都是有的
|
11
ryd994 2017-09-12 08:40:08 +08:00
mmap 的基础是 virtual memory (不是 windows 的虚拟内存)
当访问的虚拟地址不在内存里的时候,会 page fault 给内核,内核如果发现这是个 mmap,就会从硬盘读取数据到某段内存,然后把相应的内存页映射到这个虚拟地址 至于 io 过程中的复制,主要是说 read 和 write 这两个 我们看 POSIX read: ssize_t read(int fildes, void *buf, size_t nbyte); 这里 buffer 就是用户空间内存 而 io 读取是先读到内核空间的缓存里,再从缓存复制到 buf,这就是一次内存拷贝 写也是同理 @xenme 跳过内核?喵喵喵?内核还负责翻译虚拟地址呢,你这么厉害能跳过内核了?只有 DOS 才能这么玩 |
12
stephen9357 2017-09-12 11:50:05 +08:00
@kaiser1992 你说的普通 IO 是指什么?
使用 Buffered IO 还是 Direct IO,甚至两者都不用都可以,取决于处理该 IO 的设备,可以下载 osr 的 devicetree 查看具体某个设备对象的 flags。 可以参考 ReactOS 的 IO 管理器代码 https://github.com/reactos/reactos/blob/31b47ad45e6384dd538ebfee33c4829945cf2eee/reactos/ntoskrnl/io/iomgr/iofunc.c#L2695 |
13
kaiser1992 OP @stephen9357 谢谢,directIO 的原理是不需要通过内核空间?
|
14
kaiser1992 OP @stephen9357 也就是说 DirectIO 是内存映射的一种实现?
|
15
stephen9357 2017-09-12 21:19:54 +08:00
@kaiser1992 DO_DIRECT_IO 也需要内核地址空间。如果使用 DO_BUFFERED_IO,内核会新分配一个 buffer,对内容进行读写操作,最终将该 buffer 拷贝到用户态,而 DO_DIRECT_IO 则不需要拷贝,只是把应用层传递的 buffer 在内核重新映射一次,这样两块地址空间都对应同一块物理内存,就不需要拷贝了,改了这里就是改了那里。
|
16
kaiser1992 OP @stephen9357 谢谢
|