pa3: improving performance with i/o multiplexing part 1-1: nov. 7, part 1-2: nov. 10 part 2-1: nov....
TRANSCRIPT
![Page 1: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/1.jpg)
PA3: Improving Perfor-mance with I/O Multi-
plexingPart 1-1: Nov. 7, Part 1-2: Nov. 10Part 2-1: Nov. 17, Part 2-2: Nov.20
![Page 2: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/2.jpg)
Dealing with Concurrency
• Creating new child or new thread• Expensive• Only handling 1 connection in a thread
• I/O multiplexing with event-driven programming• Multiplex input/output between multiple files (or sockets)• Select()
• When event comes, select returns• Buffered I/O (POSIX AIO)
• I/O asynchronously done in background• Libevent
• When event comes, pre-designated function is called
![Page 3: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/3.jpg)
Select()
• Select returns when there’s new event• After select returns,
it checks whether the fd is set.• If fd is set, process
the event (e.g., han-dle HTTP request)
// server exampleret = select(n, &fds, NULL, NULL, NULL);if (ret < 0) { perror(“select”);} else if (ret) { for (i = 0; i < n; i++) { if (FD_ISSET(fd_set[i], &fds)) { /* if listening fd, accept* / /* otherwise, process request */ if (fd_set[i] == listenfd) { accept(listenfd, …); } else { read(fd_set[i], …); write(fd_set[i], …); } } } }
![Page 4: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/4.jpg)
Part 1: POSIX AIO
• POSIX asynchronous I/O• aio_read(), aio_write() immediately returns• The actual read and write are processed in the back-
ground• The application can do another work without being
blocked by read() or write()• The completion of I/O can be notified by a signal
![Page 5: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/5.jpg)
Server Example using AIOstruct aiocb aiocbList[MAX_FD];
sa.sa_flags = SA_RESTART | SA_SIGINFO;sa.sa_sigaction = aioSigHandler;if (sigaction(IO_SIGNAL, &sa, NULL) == -1) exit(1);
while (1) { fd = accept(listenfd, …); if (fd < 0) continue;
/* build aio control block */ aiocbList[fd].aio_fildes = fd; aiocbList[fd].aio_buf = malloc(BUF_SIZE); aiocbList[fd].aio_nbytes = BUF_SIZE; aiocbList[fd].aio_reqprio = 0; aiocbList[fd].aio_offset = 0; aiocbList[fd].aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocbList[fd].aio_sigevent.sigev_signo = IO_SIGNAL; aiocbList[fd].aio_sigevent.sigev_value.sival_ptr = &aiocbList[fd]; s = aio_read(&aiocbList[fd]); if (s == -1) errExit("aio_read");}
![Page 6: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/6.jpg)
Server Example using AIO/* Handler for I/O completion signal */static voidaioSigHandler(int sig, siginfo_t *si, void *ucontext){ struct aiocb *acb = si->value.sival_ptr; int fd = acb->aio_fildes;
/* process the request stored in acb->aio_buf
/* write a response using aio_write() */ /* if aio_write() completes, close the connection */}
For more detail, refer to the man page of aio (in shell, $ man aio)
![Page 7: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/7.jpg)
Part 2: Libevent
• Event notification library• Execute a callback function when a specified event oc-
curs on a file descriptor• Availability-based
• If incoming connection available, it notifies• If incoming request available, it notifies• If sending buffer available, it notifies• Calls pre-registered callback function when there is event
• Use nonblocking for I/O operations• Set socket fds to nonblocking by fcntl()
![Page 8: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/8.jpg)
Server Example using libevent#include <event.h> /* for libevent */
int main() { struct event ev_accept; … /* create listening socket and set it nonblock */ … event_init();
/* register the event */ event_set(&ev_accept, listenfd, EV_READ | EV_PERSIST, OnAcceptEvent, NULL); event_add(&ev_accept, NULL);
/* start event loop */ event_dispatch();
… close(listenfd); return 0;}
![Page 9: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/9.jpg)
Server Example using libeventstatic void OnAcceptEvent(int fd, short event, void *arg){ struct event ev_read; int new_fd = accept(fd, NULL, NULL); /* set new_fd nonblocking */
event_set(&ev_read, new_fd, EV_READ, OnReadEvent, NULL); event_add(&ev_read, NULL);}
static void OnReadEvent(int fd, short event, void *arg){ struct event ev_write; char buf[BUFSIZE];
read(fd, buf, BUFSIZE); /* process the request in buffer */ /* write the response */ write(fd, response, len);}
![Page 10: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/10.jpg)
Buffer Management
• What if send buffer is full?• write() will return -1• errno will be set to EAGAIN or EWOULDBLOCK
• What you need to do?• You need to send the response again later• Remember the “state”
• Until where it was sent• Register a write event• Retry later when write event comes
• When send buffer becomes available, write event will come
![Page 11: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/11.jpg)
Remembering the Statestruct context{ char w_buf[BUFSIZE]; /* write buffer */ int fd; struct event ev_read; struct event ev_write; int off; /* buffer offset */ int rem_len; /* remaining length */};static void OnReadEvent(int fd, short event, void *arg){ struct context *ctx = (struct context *)arg; char buf[BUFSIZE];
rd = read(fd, buf, BUFSIZE); /* process the request in buffer */ /* start writing the response */ /* if not sent fully, register an event */ wr = write(fd, ctx->w_buf, ctx->rem_len); ctx->off += wr; ctx->rem_len -= wr; event_del(ctx->ev_read, NULL); event_set(ctx->ev_write, fd, EV_WRITE, OnWriteEvent, ctx); event_add(ctx->ev_write, NULL);}
![Page 12: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/12.jpg)
Remembering the Statestatic void OnWriteEvent(int fd, short event, void *arg){ struct context *ctx = (struct context *)arg;
wr = write(fd, ctx->w_buf + ctx->off, ctx->rem_len); ctx->off += wr; ctx->rem_len -= wr;
/* if done writing */ if (ctx->rem_len == 0) { event_del(ctx->ev_write, NULL); close(fd); free(ctx); }}
![Page 13: PA3: Improving Performance with I/O Multiplexing Part 1-1: Nov. 7, Part 1-2: Nov. 10 Part 2-1: Nov. 17, Part 2-2: Nov.20](https://reader036.vdocuments.us/reader036/viewer/2022082322/5697bfa81a28abf838c99349/html5/thumbnails/13.jpg)
Evaluation
• 50 pt for each part• 20 pt for basic functionality testing
• Ina.kaist.ac.kr, yahoo, naver• 20 pt for performance and robustness testing
• Testing with ab (ApachBench)• Many consecutive requests• Many concurrent connections
• 10 pt for report• Performance comparison• Threaded vs. AIO vs. libevent