Hi, I was invited to participate in corosio review process. I noticed some inefficiency in IOCP usage.
Steps to reproduce:
- Get a Windows machine.
- Get
corosio from this repository.
- Somehow figure out how to build
corosio. It is not easy as "just" a double-clicking on a Visual Studio solution project file, or "running" the default CMake file from command line. I ended up manually modifying the CMake file to include capy dependency.
- Run the
corosio_example_hash_server example porject.
- There is a server being launched, it is listening for clients, waiting for them to connect, or whatnot.
- The server is using a
IOCP technology from Windows (basically epoll).
- So far so good.
- But. The server is sleeping on the
IOCP with a 500 ms timeout.
This is not great. This means that if there is no events being posted to the IOCP for long periods of time, the waiting process wakes up regardless. Only to check some internal state and go back to the sleep again waiting for more IOCP events. This is wasteful. This adds unnecessary additional pressure to the OS kernel scheduler waking up the process and running it only to do "almost nothing". This brings the memory pages of the server app into working set, possibly reducing available amount of RAM usable for other task that are actually doing something useful. Not to mention possible swap activity.
Why is the reason waking up the server thread periodically? To check some internal state and act according to it? The server app should consume 0.00 % of CPU if there are no clients. Absolutely zero. If you really need to check some internal state and do something based on its value - then there is better solution than waking up twice every second. Post an event to the IOCP at the moment the internal state is being changed (right after the change). This will wake up the server process only when there is actually some work to be done. There is PostQueuedCompletionStatus Windows function for this purpose. It can carry two pointers and one integer of arbitrary payload. One is of type LPOVERLAPPED but in reality it is a pointer that does not need to point to any overlapped structure. Second is of type ULONG_PTR, basically uintptr_t. Third is of type DWORD, basically unsinged 32bit integer. Please make use of these three variables. Windows does not care about where they are poiting to, they can be arbitrary values.
Hi, I was invited to participate in
corosioreview process. I noticed some inefficiency in IOCP usage.Steps to reproduce:
corosiofrom this repository.corosio. It is not easy as "just" a double-clicking on a Visual Studio solution project file, or "running" the default CMake file from command line. I ended up manually modifying the CMake file to includecapydependency.corosio_example_hash_serverexample porject.IOCPtechnology from Windows (basicallyepoll).IOCPwith a500 mstimeout.This is not great. This means that if there is no events being posted to the
IOCPfor long periods of time, the waiting process wakes up regardless. Only to check some internal state and go back to the sleep again waiting for moreIOCPevents. This is wasteful. This adds unnecessary additional pressure to the OS kernel scheduler waking up the process and running it only to do "almost nothing". This brings the memory pages of the server app into working set, possibly reducing available amount of RAM usable for other task that are actually doing something useful. Not to mention possible swap activity.Why is the reason waking up the server thread periodically? To check some internal state and act according to it? The server app should consume
0.00 %of CPU if there are no clients. Absolutely zero. If you really need to check some internal state and do something based on its value - then there is better solution than waking up twice every second. Post an event to theIOCPat the moment the internal state is being changed (right after the change). This will wake up the server process only when there is actually some work to be done. There isPostQueuedCompletionStatusWindows function for this purpose. It can carry two pointers and one integer of arbitrary payload. One is of typeLPOVERLAPPEDbut in reality it is a pointer that does not need to point to any overlapped structure. Second is of typeULONG_PTR, basicallyuintptr_t. Third is of typeDWORD, basically unsinged 32bit integer. Please make use of these three variables. Windows does not care about where they are poiting to, they can be arbitrary values.