[web-devel] Making throughput much better
Kazu Yamamoto ( 山本和彦 )
kazu at iij.ad.jp
Mon Jul 22 10:28:51 CEST 2013
Hi all,
Cc: Simon Marlow
I think I found a way to make the throughput of web servers much
better. In short, put "Control.Concurrent.yield" after sending
something. This enables good schedule shaping.
Typical code for web servers is like this:
loop = do
keepAlive <- receiveRequest
sendResponse
when keepAlive loop
With this code, a typical sequence of system calls is like this:
recvfrom(13, ) -- thread A
sendto(13, ) -- thread A
recvfrom(13, ) = -1 EAGAIN -- thread A
epoll_ctl(3, ) -- IO manager
recvfrom(14, ) -- thread B
sendto(14, ) -- thread B
recvfrom(14, ) = -1 EAGAIN -- thread B
epoll_ctl(3, ) -- IO manager
Since each thread calls recvfrom() immediately after sendto(), the
possibility that recvfrom() can receive a request is low. This
involves the IO manager.
To make the possibility higher, I put "yield" after sendResponse:
loop = do
keepAlive <- receiveRequest
sendResponse
yield
when keepAlive loop
Yield pushes its Haskell thread onto the end of thread queue. So,
another thread can work. During the work of other threads, a request
message would arrive.
recvfrom(13, ) -- thread A
sendto(13, ) -- thread A
recvfrom(14, ) -- thread B
sendto(14, ) -- thread B
recvfrom(13, ) -- thread A
sendto(13, ) -- thread A
I tested this idea on SimpleServer and confirmed that its throughput
is doubled:
No yield: 58,152 req/s (https://gist.github.com/AndreasVoellmy/4184520#file-simpleserver-hs)
Yield: 113,048 req/s (https://gist.github.com/kazu-yamamoto/6051118#file-simpleserver2-hs)
Unfortunately, yield does not work for Warp as expected. It does not
pass control to another thread and behaves as used to be.
So, my question: why doesn't "yield" work in Warp? ResourceT is doing
a special thing? My code change is here:
https://github.com/yesodweb/wai/commit/4e9c6316ad59cd87be13000d15df8e6fd7c311f1
I'm using GHC head (with multicore IO manager). I'm sure that the
following patch to fix the bug of yield is applied:
https://github.com/ghc/ghc/commit/66839957a376dbe85608822c1820eb6c99210883
P.S.
It would be appreciated if someone tries this idea on other web
servers.
--Kazu
More information about the web-devel
mailing list