Re: [PATCH v2 2/4] csum-file.h: increase hashfile buffer size
- From
Jeff King <peff@peff.net>
- Date
- May 18, 2021, 07:31 UTC
- Message-ID
- <YKNtUKIHoCCOMYmn@coredump.intra.peff.net>
- In-Reply-To
- <9dc602f6c4221e2259778842ec3d1eda57508333.1621254292.git.gitgitgadget@gmail.com>
On Mon, May 17, 2021 at 12:24:50PM +0000, Derrick Stolee via GitGitGadget wrote:
Show 22 quoted lines
> From: Derrick Stolee <dstolee@microsoft.com> > > The hashfile API uses a hard-coded buffer size of 8KB and has ever since > it was introduced in c38138c (git-pack-objects: write the pack files > with a SHA1 csum, 2005-06-26). It performs a similar function to the > hashing buffers in read-cache.c, but that code was updated from 8KB to > 128KB in f279894 (read-cache: make the index write buffer size 128K, > 2021-02-18). The justification there was that do_write_index() improves > from 1.02s to 0.72s. > > There is a buffer, check_buffer, that is used to verify the check_fd > file descriptor. When this buffer increases to 128K to fit the data > being flushed, it causes the stack to overflow the limits placed in the > test suite. By moving this to a static buffer, we stop using stack data > for this purpose, but we lose some thread-safety. This change makes it > unsafe to write to multiple hashfiles across different threads. > > By adding a new trace2 region in the chunk-format API, we can see that > the writing portion of 'git multi-pack-index write' lowers from ~1.49s > to ~1.47s on a Linux machine. These effects may be more pronounced or > diminished on other filesystems. The end-to-end timing is too noisy to > have a definitive change either way.
I think there is one thing missing from this commit message: why we want to do this. You mentioned that read-cache got larger by using a bigger buffer. But here we use a bigger buffer, and it produces no improvement larger than the noise. And on top of it, you describe the static-buffer downsides. So why not just skip it? :)
And the answer is in the larger series: we want to be able to make use of the hashfile API in read-cache, but without regressing the performance. One sentence at the end of the first paragraph would clarify that quite a bit, I think.
Show 14 quoted lines
> +static void verify_buffer_or_die(struct hashfile *f,
> + const void *buf,
> + unsigned int count)
> +{
> + static unsigned char check_buffer[WRITE_BUFFER_SIZE];
> + ssize_t ret = read_in_full(f->check_fd, check_buffer, count);
> +
> + if (ret < 0)
> + die_errno("%s: sha1 file read error", f->name);
> + if (ret != count)
> + die("%s: sha1 file truncated", f->name);
> + if (memcmp(buf, check_buffer, count))
> + die("sha1 file '%s' validation error", f->name);
> +}Does this have to use the same-size buffer? We could read and check smaller chunks, like:
while (count > 0) {
static unsigned char chunk[1024];
unsigned int chunk_len = sizeof(chunk) < count ? sizeof(chunk) : count;
ssize_t ret = read_in_full(f->check_fd, chunk, chunk_len);if (ret < 0) ... if (ret != count) ... if (memcmp(buf, chunk, chunk_len)) ... buf += chunk_len; count -= chunk_len; }
We may prefer to use the larger buffer size for performance, but I think this "check" mode is only used for "index-pack --verify" and similar. The performance may matter a lot less to us there than for more frequently used code paths like index writing.
I don't have a strong preference either way, but it's nice to avoid introducing non-reentrancy to a function (Junio's heap suggestion is also quite reasonable).
-Peff