/* gcc -Wall lio_listio.c -lrt * * Written for testing lio_listio() performance while demultiplexing a huge stream-file, * eg. during recovery of a crashed server: extract 1 transaction log out of, say 32 multiplexed logstreams * * example performance for block-aligned data: FEILSIZE=1369084021 (bytes) * time /tmp/lio_listio * real 0m23.075s * travelspeed = 1369084021 / 23 = 5.95e+07 * extractspeed = travelspeed / (STEPSIZE/BUFSIZE) = 1.86e+06 5-10 MByte would be nicer (the 1 tera SATA disk - no raid - can do 40+Mbyte in streaming mode). * Actual extractspeed will be even worse, since this was on 4kbyte block boundary. * Example performance for non-block-aligned data (and 5000 byte chunks, which is rather suboptimal): FILESIZE = 1937838067 TIME=33.803 TRAVELSPEED=FILESIZE/TIME TRAVELSPEED = 5.7327e+07 extractspeed=TRAVELSPEED/40 extractspeed = 1.4332e+06 */ #include #include #include #include #define BUFSIZE 5000 #define MBUFSIZE (BUFSIZE+8) #define STEPSIZE (200001) #define FILESIZE 1937838067 #define MAX_LIST ((int)(FILESIZE/STEPSIZE)) struct aiocb aiocbs[MAX_LIST]; struct aiocb *list[MAX_LIST]; int fd, ret; char *bigbuf; /* will be [MBUFSIZE * MAX_LIST]; */ int main(int argc, char** argv) { int i; /* ln -s yourHUGEfile.avi bigfile.dat and #define MAX_LIST filesize / STEPSIZE */ fd = open( "bigfile.dat", O_RDONLY ); if (fd < 0) perror("open"); /* Zero out the aiocb structure (recommended) */ bzero( (char *)aiocbs, MAX_LIST * sizeof(struct aiocb) ); bzero( (char *)list, sizeof(list) ); // overwritten inside the for below: if(NULL == (bigbuf = malloc( MBUFSIZE * MAX_LIST ))) perror("malloc"); ; /* Prepare the first aiocb */ for (i=0; iaio_fildes = fd; // if(NULL == (ap->aio_buf = malloc( (BUFSIZE & ~7) + 8))) perror("malloc"); ap->aio_buf = &bigbuf[i * MBUFSIZE]; ap->aio_nbytes = BUFSIZE; ap->aio_offset = i*STEPSIZE; // next_offset; ap->aio_lio_opcode = LIO_READ; } ret = lio_listio( LIO_WAIT, list, MAX_LIST, NULL ); if (ret < 0) perror("lio_listio"); /* while ( aio_error( &my_aiocb ) == EINPROGRESS ) ; * * if ((ret = aio_return( &my_iocb )) > 0) { * got ret bytes on the read * } else { * read failed, consult errno * } */ return 0; }