c - AF_UNIX socket overhead? -
i'm seeing couple strange things pair of af_unix sockets created call such as:
socketpair(af_unix, sock_stream, 0, sfd); where sfd int[2] array file descriptors.
first, default buffer size seems 122k (124928 bytes), rather /proc/sys/net (such wmem_default set 128k). know cause of strange buffer size?
second, when writing small messages through socket (8 bytes). can write 423 of them before write blocks, 8*423 = 3384 bytes, odd size. messages acting though they're taking 295 + little bytes each. what's source of overhead?
running on rhel6 (2.6.32, 64-bit)
i wrote program try different sizes of data compare overhead costs:
#include <errno.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define data_size 4 void run(size_t size) { int sfd[2]; if (socketpair(af_unix, sock_stream, 0, sfd) == -1) { perror("error"); } int sndbuf, sbsize = sizeof(sndbuf); getsockopt(sfd[0], sol_socket, so_sndbuf, &sndbuf, (socklen_t*)&sbsize); printf("data size: %zd\n", size); char buff[size]; size_t wrote=0; (size_t ii=0; ii < 32768; ii++) { if ((send(sfd[0], buff, size, msg_dontwait) == -1) && (errno == eagain)) { wrote = ii; break; } } printf("wrote: %zd\n", wrote); if (wrote != 0) { int bpm = sndbuf/wrote; int oh = bpm - size; printf("bytes/msg: %i\n", bpm); printf("overhead: %i\n", oh); printf("\n"); } close(sfd[0]); close(sfd[1]); } int main() { int sfd[2]; socketpair(af_unix, sock_stream, 0, sfd); int sndbuf, sbsize = sizeof(sndbuf); getsockopt(sfd[0], sol_socket, so_sndbuf, &sndbuf, (socklen_t*)&sbsize); printf("buffer size: %i\n\n", sndbuf); close(sfd[0]); close(sfd[1]); (size_t ii=4; ii <= 4096; ii *= 2) { run(ii); } } which gives:
buffer size: 124928 data size: 4 wrote: 423 bytes/msg: 295 overhead: 291 data size: 8 wrote: 423 bytes/msg: 295 overhead: 287 data size: 16 wrote: 423 bytes/msg: 295 overhead: 279 data size: 32 wrote: 423 bytes/msg: 295 overhead: 263 data size: 64 wrote: 423 bytes/msg: 295 overhead: 231 data size: 128 wrote: 348 bytes/msg: 358 overhead: 230 data size: 256 wrote: 256 bytes/msg: 488 overhead: 232 data size: 512 wrote: 168 bytes/msg: 743 overhead: 231 data size: 1024 wrote: 100 bytes/msg: 1249 overhead: 225 data size: 2048 wrote: 55 bytes/msg: 2271 overhead: 223 data size: 4096 wrote: 29 bytes/msg: 4307 overhead: 211 versus using pipe there's lot of overhead:
data size: 4 wrote: 16384 bytes/msg: 4 overhead: 0 data size: 8 wrote: 8192 bytes/msg: 8 overhead: 0 data size: 16 wrote: 4096 bytes/msg: 16 overhead: 0 data size: 32 wrote: 2048 bytes/msg: 32 overhead: 0 data size: 64 wrote: 1024 bytes/msg: 64 overhead: 0 data size: 128 wrote: 512 bytes/msg: 128 overhead: 0 data size: 256 wrote: 256 bytes/msg: 256 overhead: 0 data size: 512 wrote: 128 bytes/msg: 512 overhead: 0 data size: 1024 wrote: 64 bytes/msg: 1024 overhead: 0 data size: 2048 wrote: 32 bytes/msg: 2048 overhead: 0 data size: 4096 wrote: 16 bytes/msg: 4096 overhead: 0
take @ socket(7) man page. there section reads:
so_sndbuf sets or gets maximum socket send buffer in bytes. kernel doubles value (to allow space bookkeeping overhead) when set using setsockopt(2), , doubled value returned getsockopt(2). default value set /proc/sys/net/core/wmem_default file , maximum allowed value set /proc/sys/net/core/wmem_max file. minimum (doubled) value option 2048.
so appears overhead hold bookkeeping information kernel.
Comments
Post a Comment