Hi all, after studying the ws2_32 dll code for some time while looking for ways to optimize it I started wondering why is the wineserver required (please don't stop reading yet).
make test takes 45 seconds in my machine while it takes 25 seconds in a XP VM running on the same machine. The culprit is test_send() [1] which takes 24 seconds in wine and 1.8 seconds in windows.
This long time is related to the 1 million recv() calls in test_send(). Each call to recv() has to call wineserver to do a enable_event(FD_READ) operation, if you comment that line out [2] wine magically takes 1.7 seconds, just like windows does (obviously commenting that line generaters other errors related to event sequences).
So, in simple words: what if we move all wineserver socket code to a thread that is started in the ws2_32 DLL. I know this may sound very silly for the experienced wine developers, maybe some operations are impossible without the wineserver, maybe there is much more things affected, but I think it's better to ask and get crushed with (hopefully) constructive criticism than forget about the idea.
My main objective with this is to speedup the whole implementation and properly implement the select call (different socket states result in different checks required) and WSACleanup call (which needs to close every open socket on last cleanup) and some other get/setsockopt stuff.
[1] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/tests/sock.c#l4... [2] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/socket.c#l6684
Best wishes, Bruno
That wouldn't always work: in theory, DuplicateHandle() could transmit the socket to another process, which wouldn't have the same ws2_32 thread.
We could speed up calls to the wineserver, which involve at least 4 system calls, 2 context switches, and 4 memory copies (in and out of the UNIX socket's buffers), by porting the wineserver to be a kernel module on the underlying *nix kernel, so that it only needs a single system call, zero context switches, and zero memory copies. I know Transgaming was considering this years ago - don't know how far they got - but I imagine it to be extremely difficult. Maybe it's possible to port only a small part of it that deals with performance critical areas, like sockets and synchronization, while the rest stays running as a user space application?
Damjan
On Mon, May 26, 2014 at 5:10 PM, Bruno Jesus 00cpxxx@gmail.com wrote:
Hi all, after studying the ws2_32 dll code for some time while looking for ways to optimize it I started wondering why is the wineserver required (please don't stop reading yet).
make test takes 45 seconds in my machine while it takes 25 seconds in a XP VM running on the same machine. The culprit is test_send() [1] which takes 24 seconds in wine and 1.8 seconds in windows.
This long time is related to the 1 million recv() calls in test_send(). Each call to recv() has to call wineserver to do a enable_event(FD_READ) operation, if you comment that line out [2] wine magically takes 1.7 seconds, just like windows does (obviously commenting that line generaters other errors related to event sequences).
So, in simple words: what if we move all wineserver socket code to a thread that is started in the ws2_32 DLL. I know this may sound very silly for the experienced wine developers, maybe some operations are impossible without the wineserver, maybe there is much more things affected, but I think it's better to ask and get crushed with (hopefully) constructive criticism than forget about the idea.
My main objective with this is to speedup the whole implementation and properly implement the select call (different socket states result in different checks required) and WSACleanup call (which needs to close every open socket on last cleanup) and some other get/setsockopt stuff.
[1] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/tests/sock.c#l4... [2] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/socket.c#l6684
Best wishes, Bruno
On 05/26/2014 09:31 AM, Damjan Jovanovic wrote:
That wouldn't always work: in theory, DuplicateHandle() could transmit the socket to another process, which wouldn't have the same ws2_32 thread.
I don't know much about winsock and wineserver and such, but would it be possible for a handle to track whether it's been duplicated from/to another process and only involve wineserver when it has been?
On Mon, May 26, 2014 at 3:23 PM, Chris Robinson chris.kcat@gmail.com wrote:
On 05/26/2014 09:31 AM, Damjan Jovanovic wrote:
That wouldn't always work: in theory, DuplicateHandle() could transmit the socket to another process, which wouldn't have the same ws2_32 thread.
I don't know much about winsock and wineserver and such, but would it be possible for a handle to track whether it's been duplicated from/to another process and only involve wineserver when it has been?
You actually need to use WSADuplicateSocket[A|W] on sockets, so it's conceivable that we could keep a record of which handles have been duplicated for other processes.
Best, Erich
We could speed up calls to the wineserver, which involve at least 4 system calls, 2 context switches, and 4 memory copies (in and out of the UNIX socket's buffers), by porting the wineserver to be a kernel module on the underlying *nix kernel, so that it only needs a single system call, zero context switches, and zero memory copies. I know Transgaming was considering this years ago - don't know how far they got - but I imagine it to be extremely difficult. Maybe it's possible to port only a small part of it that deals with performance critical areas, like sockets and synchronization, while the rest stays running as a user space application?
This conversation reminds me of this blog; http://www.linuxtoday.com/developer/2010060303135OSKNDV ...from a few years ago, comparing 'longene' or Linux Unified kernel vs Wine. The project doesn't appear to be active, but there is some source code here; https://sourceforge.net/projects/longene/files/longene/longene-0.3.2/source/ ...
I've never used it, but did take a look at one point. [back when].
cheerz
Jordan
Damjan
On Mon, May 26, 2014 at 5:10 PM, Bruno Jesus 00cpxxx@gmail.com wrote:
Hi all, after studying the ws2_32 dll code for some time while looking for ways to optimize it I started wondering why is the wineserver required (please don't stop reading yet).
make test takes 45 seconds in my machine while it takes 25 seconds in a XP VM running on the same machine. The culprit is test_send() [1] which takes 24 seconds in wine and 1.8 seconds in windows.
This long time is related to the 1 million recv() calls in test_send(). Each call to recv() has to call wineserver to do a enable_event(FD_READ) operation, if you comment that line out [2] wine magically takes 1.7 seconds, just like windows does (obviously commenting that line generaters other errors related to event sequences).
So, in simple words: what if we move all wineserver socket code to a thread that is started in the ws2_32 DLL. I know this may sound very silly for the experienced wine developers, maybe some operations are impossible without the wineserver, maybe there is much more things affected, but I think it's better to ask and get crushed with (hopefully) constructive criticism than forget about the idea.
My main objective with this is to speedup the whole implementation and properly implement the select call (different socket states result in different checks required) and WSACleanup call (which needs to close every open socket on last cleanup) and some other get/setsockopt stuff.
[1] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/tests/sock.c#l4... [2] http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ws2_32/socket.c#l6684
Best wishes, Bruno