Closed Zabrane closed 1 year ago
That example is doing malloc, memcpy and free every time it streams a chunk to kernel, so I wouldn't use it for benchmarking, esp. not with large data. And if you see double frees then it's pretty broken.
You probably want a pre-allocated ring buffer to add/remove to/from if you benchmark
@uNetworkingAB could you please help us to adapt the echo TCP example to use a pre-allocated ringbuffer
?
Any test code will be more than welcome. I really want to get rid of this proprietary server.
That example is doing malloc, memcpy and free every time it streams a chunk to kernel, so I wouldn't use it for benchmarking, esp. not with large data. And if you see double frees then it's pretty broken.
The benchmark consists of sending and receiving a single character
as fast as possible. Thus, no large data is involved. Just a single char.
void bsd_socket_nodelay(LIBUS_SOCKET_DESCRIPTOR fd, int enabled) { setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *) &enabled, sizeof(enabled)); }
bsd_socket_nodelay(us_poll_fd((struct us_poll_t *)s), 0);
You probably want to run this in on_open to disable TCP_NODELAY - pretty sure your proprietary variant has TCP_NODELAY=false, we have it true by default
@uNetworkingAB didn't change anything even with static buffer (no malloc involved, 1 big global alloc) and TCP_NODELAY
set to false
per your recommendation.
Linux:
Destination: [127.0.0.1]:3000
Total data sent: 11.7 MiB
Total data received: 6.0 MiB
Bandwidth per channel: 29.729⇅ Mbps
Test duration: 5.00832 s.
@uNetworkingAB Hi. How can i set the socket's buffers
size when using uSockets
?
To get this:
setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz));
setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sz, sizeof(sz));
Does uSockets
set the socket to non-blocking
?
fcntl(s, F_SETFL, O_NONBLOCK, s)
@uNetworkingAB I've noticed that you perform a socket write
in the on_echo_socket_data callback
. Why?
If i don't write
during reads
, the on_echo_socket_writable
callback's never called.
struct us_socket_t *on_echo_socket_data(struct us_socket_t *s, char *data, int length) {
struct echo_socket *es = (struct echo_socket *) us_socket_ext(SSL, s);
/* don't write, just buffer up the number of 'x' to send back */
es->length += length;
return s;
}
Could you please shed some light on the underlying uSockets
design?
If you want to pay for consulting time you can send me such an email and we can set it up. It's becoming obvious that you're benchmarking apples vs. carrots here, as the echo_server doesn't do what your alternative does. With some rough math you can infer that you must be doing 3.8 billion messages (chars) per second, which is 0.1 nanosecond a pop, which is not the case. So it's an apple vs. carrot comparison
While hammering the
echo_server.c
(i deleted this line + setSSL=0
), i got this error:The performances are also poor:
Is there a way to increase the
receive
(resp.send
) buffer?We are trying to replace an old proprietary TCP sever with uSockets. Here's what we can get already:
This is 3x order of magnitude faster than
uSockets
.More or less same result under Linux (
Ubuntu-20.04
LTS):Test result: