On Fri, 15 Oct 2010 03:08:23 +0400, Andrei Alexandrescu <[email protected]> wrote:

http://docs.google.com/viewer?a=v&q=cache:K15RE_6zxSwJ:citeseerx.ist.psu.edu/viewdoc/download%3Fdoi%3D10.1.1.134.4874%26rep%3Drep1%26type%3Dpdf+zero+copy+i/o&hl=en&gl=us&pid=bl&srcid=ADGEESjBkiUxG4hRImVjOFy886GrJxRuhFcePjbadiUw9h1c_iicbhhArOgd55vpk0tP6ST4KjhY1j6rl1_PN-msIExUvxSPJWuXfQTbljj4ZYyutY6wvp3mc3t2LuA2-5kKPbbEp7z6&sig=AHIEtbSmuH-Y2AGdwSQxyJcbBXLRB3mJdg


Andrei

That paper is an ancient one and the API they demonstrated isn't a good one. It is a huge step backward for a language with a garbage collector to ask users to free buffers manually when they don't need them. You can't do it automatically upon next read/write operation because user can still have a pointer to it. In general, you can't reuse old buffer and it means you must allocate new one every time you issue an I/O request, and memory allocation is a more expensive operation than a memcpy.

In many OS documentations (e.g. in Windows and Sony consoles that use Linux kernel) it is stated that I/O operations often use provided buffers directly (if an underlying hardware allows to), you usually don't need to do anything special for that to occur (in PlayStation Portable read requires you buffer to be aligned at 4 bytes boundary, it will fail otherwise, but when was last time you used an unaligned buffer?).

IIRC, D memory allocator aligns memory at 16 bytes boundary, and it is very strange to provide an unaligned slice the read(). However, if Stream buffers anything, there can be N bytes stored in the buffer, and N can be unaligned. In this case, you have to copy these N bytes to the user-provided buffer, and then call osSpecificRead(fd, userBuffer.ptr + N, userBuffer.length - N); As a result, userBuffer.ptr + N can now be unaligned, and direct io is impossible in this case. Conclusion: Stream interface should not do any buffering, all it should do is call osSpecificRead on a user-provided buffer directly.

Reply via email to