-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merging changes with memmapix #92
Comments
I think the main change there is unconditionally swapping out I guess we could add a feature for swapping out those two system call layers, e.g. [dependencies]
libc = { version = "0.2", optional = true }
rustix = { version = "0.35", features = ["fs", "mm", "param"], optional = true }
[features]
default = ["libc"] but I still have no heard a good motivation as for why the additional complexity for maintaining both implementations is required. |
My primary motivation is to have async memmap support for crates like pmtiles, which uses @al8n's fmmap -- a higher-level lib based on the But obviously it would be more resilient if the underlying libs converge -- so they are maintained and looked at by more people. CC: @lseelenbinder |
Looking at the complete diff against this repository, this does not seem to be the case. The only API change appears to be swapping out our own |
Here my first question would be what that means in practical terms? The only asynchronous operation I can think of supported by the system call interface is flushing/syncing, but that would still not make a good future as there is not notification mechanism as for when the page cache is done flushing the changes to disk. |
For example, the "async/Tokio" support in
EDIT: Even |
Per @lseelenbinder reply here, any time a blocking call is made in an async environment (e.g. a web server), one should use Tokio's block_in_place:
So while you are correct that the underlying API is not async, the higher level code would much rather use it in async to avoid performance bottlenecks -- which means the higher level memmap wrapper like fmmap should do all that bookkeeping. |
Having a crate which wraps accesses to file-backed memory maps into |
As the troubles around the They also have significant downsides: |
Note that this is actually worse than just calling a blocking system call like |
That's a good observation @adamreichold—I had assumed |
This would not be an automatic conclusion for me personally: Since the underlying system calls do not support notifying an I/O reactor and usage of |
My arguments from the last time this was brought up still stand. The benefits of The main downside of |
Using |
I might be misunderstanding the issue, but it seems adding optional rustix support will allow users to have a C-free binary, which is desirable in some cases, especially when one tries to limit unsafe code |
While I do see the build-time simplifications of not needing a working C toolchain, this is usually a given on Linux. To be honest, the aim of being "free of C code" seems a bit religious to me. Easily interfacing with code written in other languages whether it is via linking, exchanging data via file systems and networks or just running on a kernel written in C is a feature, not a bug IMHO.
The unsafe code required to interface with the |
I agree that we should try to stay away from the religious aspect:) my thinking is that if someone needs to use rustix based code, it would be silly to make libc a hard requirement of a small mmap wrapper lib if there is enough interest to add and maintain that addition. Having a separate independent rustix based code simply moves the complexity of maintaining compatible interface to some wrapper or each lib user - not good for ecosystem health (plus it hinders rustix development because it adds another barrier of entry) |
This is basically the situation in which #89 stalled: Complicating the maintenance of this crate due to internal requirements without further explanation of the rationale behind those requirements is not a convincing proposition. Which leaves us with
and
as the main tangible benefits. Weighing these against the increase in complexity for this code base can go either way, but it is not automatic IMHO. Especially since we would most likely want to keep both code paths alive, the one based on Personally, I am not strictly against adding a Footnotes
|
@lseelenbinder Uff, I just noticed that what we discussed has another implication: While page faults block the whole process, thread-based tools like Footnotes
|
I fully agree with @adamreichold here. First, I definitely do not plan to support Second, I personally don't see any benefits in using Third, PS: I do not use or familiar with async, therefore I cannot comment this aspect, but I don't see how |
Since the async support in |
@adamreichold I searched without success for verification of the "block the whole process" bit—because it surprised me. I personally find it unintuitive, because I'm most familiar with high performance Assuming it's true, we're pretty much dead-in-the-water with regard to If all that is true, I'll drop using |
I think https://lwn.net/Articles/932298/ is a nice up-to-date entry point for this particular topic. I guess the situation is also bit a more nuanced than "always block the whole process" but rather "only one file-backed page fault can happen per process" which will only block the whole process when everyone tries to resolve page faults. The underlying issue is that these address space changes currently rely on the single Finally, as discussed in the linked article work is underway to alleviate this issue but it just now being implemented. Personally, if scalable file I/O for an async service is the target, I would still recommend avoiding
Not that you can reduce the number of system calls using positioned I/O, e.g. |
@adamreichold Thank you—I appreciate the time you've taken to dig through these issues with all of us! That makes a lot more sense now—and lock contention is certainly the bane of high performance scalability in my experience.
TIL. Really helpful. |
Note that the status quo is considerably worse than lock contention, i.e. the communication overhead of many threads of execution acquiring and releasing a lock which is especially problematic when the critical sections are short. For now, the main scalability issue for page faults is doing I/O while holding the lock. This means that the threads not only fight for the cache line holding the futex and queue up to access it, but it also means that I/O is serialized which means queue depths cannot be filled and I/O device utilization stays low. Which is especially problematic with modern flash devices which require a certain queue depth before becoming effective. This is also particularly vexing as a high degree of I/O parallelism is usually a benefit of memory maps when the kernel issues multiple readahead requests on its own while the mapping process can continue with its work. |
Hi, I noticed that @al8n has made some changes in their fork https://github.com/al8n/memmapix, while this repo has also done some diverging work. This repo clearly has far more downloads/community following, so I wonder if it would be possible to merge some/all of the memmapix changes into this repo, or what's your future plans for this repo?
Both efforts would clearly benefit the community, and highly appreciated, thank you all!
P.S. The
memmapix
repo doesn't have issues tab for some reason, so I couldn't ask for it there.The text was updated successfully, but these errors were encountered: