6 ms·
> Imagine a world where all system calls are asynchronous, all events and system calls return values are posted onto a message queue and you could drain the mes
by jcrites 12y ago
> Imagine a world where all system calls are asynchronous, all events and system calls return values are posted onto a message queue and you could drain the message queue with a single interaction with the kernel.
Interesting idea. Have existing OSes explored this? What are the major technical challenges and proposed solutions? Questions and ideas:
One option is to design every such API so that it can accept a batch of work. An array of structures representing the parameters to individual logical API calls. Invoke a single API call to hand off the array. Perhaps that will provide most of the achievable benefit, since I imagine these performance-intensive applications are bottlenecked on high volumes of calls to small numbers of APIs.
It would be a pain to modify every API interface in this fashion, and I imagine it will be difficult to implement those APIs.
Could the kernel provide a single batch facility accepting as input an array of structures representing API calls? The goal would be to make it possible to implement those APIs mostly like normal, such that the kernel takes responsibility for fanning out the batch into individual API invocations, in the simplest case by executing them sequentially; though the implementation of the API could also take advantage of batching as well.
Success of the calls would need to be determined through an API like select, or alternatively through IO events on the individual file descriptors being worked-on. There will need to be a canonical format for specifying the API to invoke (function pointer?) and its arguments (calling convention). I imagine this could be quite challenging to implement in general; all state will need to be managed explicitly. For example, you could not use a calling convention where the caller is expected to use another API to get details about why the last call failed (like Windows `GetLastError`), since the state will be clobbered by subsequent calls in a batch.
In terms of a mechanism, could the OS and applications communicate through concurrent data structures like the disruptor pattern rather than by direct context switching? It seems like this would potentially require passing input/output through main memory (if crossing CPUs). Unsure if this would provide a net benefit.
From a naive perspective this all seems feasible, but also sounds like a huge amount of work and the primary benefit would be for the highest of high-performance applications. Though I wonder how much overall performance would improve for typical applications if we can minimize context switching.
Potentially relevant: https://news.ycombinator.com/item?id=7679822 https://news.ycombinator.com/item?id=7679822 - Linus Torvalds on the high cost of page faults, which are more likely to happen under frequent context switching.
- adamnemecek 12y agoI believe that BeOS (and now Haiku) explored some ideas like that. I think that all (most?) OS APIs were async and message queues were used to call the APIs as well as return values from them (someone correct me if I'm wrong). This resulted in a really snappy GUI but that's about all I know about it. One major hurdle was that programming for the OS became tricky. There's this free book about BeOS which I've been meaning to read http://oreilly.com/openbook/beosprog/book/ http://oreilly.com/openbook/beosprog/book/ but never quite got around to it. You might find answers to some of your questions there.
- oofabz 12y ago>design every such API so that it can accept a batch of work I've realized some significant performance gains with this approach. The benefit was locking once to process many messages, instead of locking for every message.
- nostrademons 12y agoWasn't win32 done like that? I have vague memories of PostMessage/GetMessage/TranslateMessage/DispatchMessage loops. I never did enough Windows development to understand where the actual syscall boundaries were, but since everything was done by message passing to the main loop of your application, the API seems amenable to pumping out multiple messages in one syscall.