performance: use pread instead of lseek+read
От | Manfred Spraul |
---|---|
Тема | performance: use pread instead of lseek+read |
Дата | |
Msg-id | 3E5A6349.4060900@colorfullife.com обсуждение исходный текст |
Ответы |
Re: performance: use pread instead of lseek+read
(Tom Lane <tgl@sss.pgh.pa.us>)
|
Список | pgsql-patches |
Hi all, postgresql tries very hard to avoid calling lseek if not needed, probably to avoid doing unnecessary syscalls. What about removing lseek entirely and using the p{read,write}? pread is identical to the normal read syscall, except that it has one additional parameter: the position from which the data should be read. All recent unices support that, it's part of POSIX.1c. Attached is a patch vs the cvs tree. It seems to work - 7.3.2 with the patch applied passes the regression test suite on RH Linux. Untested with cvs-head, preproc.y causes a parser overflow. What do you think? - configure: I test for existance of pread, and assume that pwrite will exist, too. Acceptable? - Are you interested in further patches? xlog.c contains a few lseeks, but I doubt that they are in the critical path. -- Manfred diff -u -u -r -x configure pgsql.orig/configure.in pgsql/configure.in --- pgsql.orig/configure.in 2003-02-19 05:04:04.000000000 +0100 +++ pgsql/configure.in 2003-02-23 09:38:46.000000000 +0100 @@ -786,7 +786,7 @@ # SunOS doesn't handle negative byte comparisons properly with +/- return AC_FUNC_MEMCMP -AC_CHECK_FUNCS([cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync utimeutimes]) +AC_CHECK_FUNCS([cbrt fcvt getpeereid memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync utimeutimes pread]) AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>]) diff -u -u -r -x configure pgsql.orig/src/backend/storage/file/fd.c pgsql/src/backend/storage/file/fd.c --- pgsql.orig/src/backend/storage/file/fd.c 2002-09-02 08:11:42.000000000 +0200 +++ pgsql/src/backend/storage/file/fd.c 2003-02-23 09:45:41.000000000 +0100 @@ -391,7 +391,9 @@ Delete(file); /* save the seek position */ +#ifndef HAVE_PREAD vfdP->seekPos = (long) lseek(vfdP->fd, 0L, SEEK_CUR); +#endif Assert(vfdP->seekPos != -1L); /* close the file */ @@ -462,6 +464,7 @@ ++nfile; } +#ifndef HAVE_PREAD /* seek to the right position */ if (vfdP->seekPos != 0L) { @@ -470,6 +473,7 @@ returnValue = (long) lseek(vfdP->fd, vfdP->seekPos, SEEK_SET); Assert(returnValue != -1L); } +#endif } /* @@ -877,11 +881,17 @@ VfdCache[file].seekPos, amount, buffer)); FileAccess(file); +#if HAVE_PREAD + returnCode = pread(VfdCache[file].fd, buffer, amount, VfdCache[file].seekPos); + if (returnCode > 0) + VfdCache[file].seekPos += returnCode; +#else returnCode = read(VfdCache[file].fd, buffer, amount); if (returnCode > 0) VfdCache[file].seekPos += returnCode; else VfdCache[file].seekPos = FileUnknownPos; +#endif return returnCode; } @@ -900,16 +910,25 @@ FileAccess(file); errno = 0; +#if HAVE_PREAD + returnCode = pwrite(VfdCache[file].fd, buffer, amount, VfdCache[file].seekPos); +#else returnCode = write(VfdCache[file].fd, buffer, amount); +#endif /* if write didn't set errno, assume problem is no disk space */ if (returnCode != amount && errno == 0) errno = ENOSPC; +#if HAVE_PREAD + if (returnCode > 0) + VfdCache[file].seekPos += returnCode; +#else if (returnCode > 0) VfdCache[file].seekPos += returnCode; else VfdCache[file].seekPos = FileUnknownPos; +#endif return returnCode; } @@ -951,12 +970,20 @@ case SEEK_SET: if (offset < 0) elog(ERROR, "FileSeek: invalid offset: %ld", offset); +#ifdef HAVE_PREAD + VfdCache[file].seekPos = offset; +#else if (VfdCache[file].seekPos != offset) VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); +#endif break; case SEEK_CUR: +#ifdef HAVE_PREAD + VfdCache[file].seekPos += offset; +#else if (offset != 0 || VfdCache[file].seekPos == FileUnknownPos) VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); +#endif break; case SEEK_END: VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence); diff -u -u -r -x configure pgsql.orig/src/include/pg_config.h.in pgsql/src/include/pg_config.h.in --- pgsql.orig/src/include/pg_config.h.in 2003-02-19 05:04:04.000000000 +0100 +++ pgsql/src/include/pg_config.h.in 2003-02-23 09:59:47.000000000 +0100 @@ -544,6 +544,9 @@ /* Define if the standard header unistd.h declares fdatasync() */ #undef HAVE_DECL_FDATASYNC +/* Define if you have pread(). Implies pwrite, too. */ +#undef HAVE_PREAD + /* Set to 1 if you have libz.a */ #undef HAVE_LIBZ
В списке pgsql-patches по дате отправления: