On Wednesday 20 April 2005 13:52, Linus Torvalds wrote: > On Wed, 20 Apr 2005, Chris Mason wrote: > > The patch below with your current tree brings my 100 patch test down to > > 22 seconds again. > > If you ever have a cache_entry bigger than 16384, your code will write > things out in the wrong order (write the new cache without flushing the > old buffer).
Whoops > Finally, if you really want to go fast, you should really try to make your > writes powers-of-two, ie fill up the buffer entirely rather than saying > "if I were to overflow, flush it now". It doesn't matter that much for > some filesystems (especially local and append-only like the patterns are > here), but it can definitely matter for the stupid ones. Well, the difference there should be pretty hard to see with any benchmark. But I was being lazy...new patch attached. This one gets the same perf numbers, if this is still wrong then I really need some more coffee. -chris
--- linus.back/read-cache.c 2005-04-20 10:14:23.268310000 -0400 +++ linus/read-cache.c 2005-04-20 14:54:28.554518320 -0400 @@ -232,11 +232,13 @@ SHA_CTX c; struct cache_header hdr; int i; + #define BUFLEN 16384 + static char buf[BUFLEN]; + int len = 0; hdr.hdr_signature = htonl(CACHE_SIGNATURE); hdr.hdr_version = htonl(1); hdr.hdr_entries = htonl(entries); - SHA1_Init(&c); SHA1_Update(&c, &hdr, offsetof(struct cache_header, sha1)); for (i = 0; i < entries; i++) { @@ -246,13 +248,37 @@ } SHA1_Final(hdr.sha1, &c); - if (write(newfd, &hdr, sizeof(hdr)) != sizeof(hdr)) - return -1; - + /* hdr is small right now, but just + * in case someone changes that... + */ + if (sizeof(hdr) < BUFLEN) { + memcpy(buf, &hdr, sizeof(hdr)); + len += sizeof(hdr); + } else { + if (write(newfd, &hdr, sizeof(hdr)) != sizeof(hdr)) + return -1; + } for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; int size = ce_size(ce); - if (write(newfd, ce, size) != size) + char *p = (char *)ce; + while(size > 0) { + int count = size; + if (count > BUFLEN - len) + count = BUFLEN - len; + memcpy(buf + len, p, count); + size -= count; + len += count; + p += count; + if (len == BUFLEN) { + if (write(newfd, buf, len) != len) + return -1; + len = 0; + } + } + } + if (len) { + if (write(newfd, buf, len) != len) return -1; } return 0;