开发者

Too many server examples: how does one determine the most applicable approach?

I'm about to implement a simple server from scratch, intending to maximum throughput (ie, accept as many requests as possible from clients, and allow scaling to as many clients as possible) on a single port on a given network connection theoretically capable of at most X bytes/sec in and Y bytes/sec out, yet keep the code as simple as possible.

How does one determine the best tradeoff between complexity of code and sufficient throughput?

For example, this page lists IOCP (AcceptEx and WSAAccept variants), then "overlap", then WSAPoll, then "simple", then "accept", as the high-to-low performing SDK examples of server performance.

It kind of implies that iocpserverex (with AcceptEx) is better than iocpserver (with WSAAccept), but doesn't really offer any proof or benchmarks. Has anyone compared the two approaches?

Forum discussions like this one state AcceptEx "should" be better, but again, with no proof.

For me, the cost of network speed has remained relatively stable for years, while faster CPUs are always getting cheaper. There must be a point of diminishing returns where it's not really worth further complicating the server code if it's already reached the ability to service the capacity of a given network connection.

What I'd really like to see is the IOCP-overlap-WSAPoll-simple-accept list (or similar comparisons, but for UDP servers) along with actual performance numbers, to give an idea of how much improvement comes with the addition of possibly more complex code. What's a good source of those kinds of benchmarks? Before actual coding, what's the best way to know a given approach will开发者_运维知识库 probably deliver sufficient throughput?


Here's a comparison I found in Network Programming For Microsoft Windows:

Too many server examples:  how does one determine the most applicable approach?


One reason that AcceptEx() generally performs better is that you have one less thread that is being context switched to; with non overlapped Accepts you tend to have a thread dedicated to looping and accepting connections. With AcceptEx() you don't, everything can be done on your IOCP threads (if you're that way inclined). Also you can create your sockets in advance, rather than having Accept create them, which may or may not be useful and/or more performant. These performance improvements probably only really show up on heavily loaded server and are, I expect, quite difficult to demonstrate in simple examples.

AcceptEx() based servers aren't actually that much more complex that standard accept() loop servers; at least once you've already gone down the IOCP route...

One way to work out how these examples perform is to test them yourself; I talk about this here on my blog and provide a link to a simple test program that can create many thousands of concurrent connections and send data over them a predetermined rates. Work out how many connections you want to scale to and then decide appropriately.

Another thing to consider is whether it IS actually more complex to use the high performance APIs once you understand them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜