]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: poll: optimize fd management functions for low register count CPUs
authorWilly Tarreau <w@1wt.eu>
Thu, 13 Dec 2012 22:34:18 +0000 (23:34 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 13 Dec 2012 22:34:18 +0000 (23:34 +0100)
Looking at the assembly code that updt_fd() and alloc/release_spec_entry
produce in the polling loops, it's clear that gcc has to recompute pointers
several times in a row because of limited spare registers. By better
grouping adjacent structure updates, we improve the code size by around
60 bytes in the fast path on x86.

include/proto/fd.h

index 127cbe08d522d93b325a341aa6654d28ae8b9ba5..3b1365d86e4ad4bd6e4f758ba8ce9821f1fcdec7 100644 (file)
@@ -89,8 +89,8 @@ static inline void updt_fd(const int fd)
        if (fdtab[fd].updated)
                /* already scheduled for update */
                return;
-       fd_updt[fd_nbupdt++] = fd;
        fdtab[fd].updated = 1;
+       fd_updt[fd_nbupdt++] = fd;
 }
 
 
@@ -100,8 +100,9 @@ static inline void alloc_spec_entry(const int fd)
        if (fdtab[fd].spec_p)
                /* FD already in speculative I/O list */
                return;
-       fd_spec[fd_nbspec++] = fd;
+       fd_nbspec++;
        fdtab[fd].spec_p = fd_nbspec;
+       fd_spec[fd_nbspec-1] = fd;
 }
 
 /* Removes entry used by fd <fd> from the spec list and replaces it with the
@@ -117,7 +118,7 @@ static inline void release_spec_entry(int fd)
                return;
        fdtab[fd].spec_p = 0;
        fd_nbspec--;
-       if (pos <= fd_nbspec) {
+       if (likely(pos <= fd_nbspec)) {
                /* was not the last entry */
                fd = fd_spec[fd_nbspec];
                fd_spec[pos - 1] = fd;