Skip to content

Commit 007062a

Browse files
sbauersfeldgitster
authored andcommitted
index-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB
index-pack and unpack-objects both read pack data from stdin through a 4 KiB static buffer. In index-pack, each fill() flushes consumed bytes to the pack file via write_or_die(), capping every write(2) at 4 KiB. unpack-objects uses the same buffer pattern for reads. On FUSE-backed filesystems every write(2) is a synchronous round trip through the FUSE protocol (userspace -> kernel -> userspace -> back), so the 4 KiB buffer turns a clone into many unnecessary tiny writes with noticeable latency overhead. Increase the buffer from 4 KiB to 128 KiB. Introduce a shared DEFAULT_IO_BUFFER_SIZE constant in git-compat-util.h (next to MAX_IO_SIZE) and use it in index-pack, unpack-objects, and the hashfile layer in csum-file (which already used 128 KiB but hardcoded the value). Pack file writes to a FUSE filesystem with writeback caching disabled during HTTPS clones of git/git (~293 MB pack): 74,958 -> 4,687 (94% fewer) Wall-clock time of git clone over HTTPS onto a FUSE passthrough filesystem with writeback caching disabled, 3 runs per variant: vscode (~1.26 GB pack): 84.5s -> 75.7s avg (10% faster) git/git (~306 MB pack): 22.6s -> 20.0s avg (11% faster) Signed-off-by: Scott Bauersfeld <sbauersfeld@g.ucla.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 94f0577 commit 007062a

4 files changed

Lines changed: 9 additions & 5 deletions

File tree

builtin/index-pack.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ static int check_self_contained_and_connected;
145145

146146
static struct progress *progress;
147147

148-
/* We always read in 4kB chunks. */
149-
static unsigned char input_buffer[4096];
148+
static unsigned char input_buffer[DEFAULT_IO_BUFFER_SIZE];
150149
static unsigned int input_offset, input_len;
151150
static off_t consumed_bytes;
152151
static off_t max_input_size;

builtin/unpack-objects.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
static int dry_run, quiet, recover, has_errors, strict;
2424
static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]";
2525

26-
/* We always read in 4kB chunks. */
27-
static unsigned char buffer[4096];
26+
static unsigned char buffer[DEFAULT_IO_BUFFER_SIZE];
2827
static unsigned int offset, len;
2928
static off_t consumed_bytes;
3029
static off_t max_input_size;

csum-file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ struct hashfile *hashfd_ext(const struct git_hash_algo *algop,
178178
f->algop = unsafe_hash_algo(algop);
179179
f->algop->init_fn(&f->ctx);
180180

181-
f->buffer_len = opts->buffer_len ? opts->buffer_len : 128 * 1024;
181+
f->buffer_len = opts->buffer_len ? opts->buffer_len : DEFAULT_IO_BUFFER_SIZE;
182182
f->buffer = xmalloc(f->buffer_len);
183183
f->check_buffer = NULL;
184184

git-compat-util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,12 @@ static inline uint64_t u64_add(uint64_t a, uint64_t b)
712712
# endif
713713
#endif
714714

715+
/*
716+
* Default buffer size for buffered I/O in index-pack, unpack-objects,
717+
* and the hashfile layer in csum-file.
718+
*/
719+
#define DEFAULT_IO_BUFFER_SIZE (128 * 1024)
720+
715721
#ifdef HAVE_ALLOCA_H
716722
# include <alloca.h>
717723
# define xalloca(size) (alloca(size))

0 commit comments

Comments
 (0)