Skip to content

Commit e3959cc

Browse files
ttaylorrgitster
authored andcommitted
pack-bitmap: pass object position to fill_bitmap_tree()
In the following commit, callers of `fill_bitmap_tree()` will be required to check the bit corresponding to their tree before calling that function. That change will reduce the overhead of setting up and tearing down stack frames for trees whose bits are already set. To prepare for that change, have callers pass in the tree's bit position in `fill_bitmap_tree()`, which will make the next commit easier to read. In the meantime, this change has a surprising and measurable benefit during bitmap generation, particularly on very large repositories. When processing sub-trees within `fill_bitmap_tree()`, the preimage of this patch did the following: while (tree_entry(&desc, entry)) { switch (object_type(entry.mode)) { case OBJ_TREE: if (fill_bitmap_tree(writer, bitmap, lookup_tree(writer->repo, &entry.oid)) < 0) { /* ... */ } /* ... */ } } , first performing the object lookup via `lookup_tree()`, and then locating its bit position within the recursive call. This patch effectively reorders those two calls so that we first discover the sub-tree's bit position, *then* load its tree. By reordering these two operations, we spend fewer CPU cycles per instruction, likely due to improved CPU dependency/cache/pipeline behavior. Comparing the results of: running `perf stat` before and after this commit, we have: +--------------+-------------+-------------+-------------------+ | | HEAD^ | HEAD | Delta | +--------------+-------------+-------------+-------------------+ | elapsed | 612.5 s | 582.4 s | -30.1 s (-4.9%) | | cycles | 2,857.3 B | 2,713.3 B | -144.0 B (-5.0%) | | instructions | 2,413.2 B | 2,415.5 B | +2.3 B (+0.1%) | | CPI | 1.184 | 1.123 | -0.061 (-5.1%) | +--------------+-------------+-------------+-------------------+ In a large repository with ~4.8M commit, and ~37.1M tree objects this change improves timing from ~612.5 seconds down to ~582.4 seconds, or a ~4.9% improvement. More importantly, the number of CPU cycles spent dropped off significantly as a result of this commit, lowering our cycles-per-instruction ratio by about ~5.1%. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent d9e49a6 commit e3959cc

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

pack-bitmap-write.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -456,20 +456,17 @@ static void bitmap_builder_clear(struct bitmap_builder *bb)
456456

457457
static int fill_bitmap_tree(struct bitmap_writer *writer,
458458
struct bitmap *bitmap,
459-
struct tree *tree)
459+
struct tree *tree,
460+
uint32_t pos)
460461
{
461462
int found;
462-
uint32_t pos;
463463
struct tree_desc desc;
464464
struct name_entry entry;
465465

466466
/*
467467
* If our bit is already set, then there is nothing to do. Both this
468468
* tree and all of its children will be set.
469469
*/
470-
pos = find_object_pos(writer, &tree->object.oid, &found);
471-
if (!found)
472-
return -1;
473470
if (bitmap_get(bitmap, pos))
474471
return 0;
475472
bitmap_set(bitmap, pos);
@@ -482,8 +479,12 @@ static int fill_bitmap_tree(struct bitmap_writer *writer,
482479
while (tree_entry(&desc, &entry)) {
483480
switch (object_type(entry.mode)) {
484481
case OBJ_TREE:
482+
pos = find_object_pos(writer, &entry.oid, &found);
483+
if (!found)
484+
return -1;
485485
if (fill_bitmap_tree(writer, bitmap,
486-
lookup_tree(writer->repo, &entry.oid)) < 0)
486+
lookup_tree(writer->repo,
487+
&entry.oid), pos) < 0)
487488
return -1;
488489
break;
489490
case OBJ_BLOB:
@@ -575,8 +576,14 @@ static int fill_bitmap_commit(struct bitmap_writer *writer,
575576
}
576577

577578
while (tree_queue->nr) {
578-
if (fill_bitmap_tree(writer, ent->bitmap,
579-
prio_queue_get(tree_queue)) < 0)
579+
struct tree *t = prio_queue_get(tree_queue);
580+
int found;
581+
582+
pos = find_object_pos(writer, &t->object.oid, &found);
583+
if (!found)
584+
return -1;
585+
586+
if (fill_bitmap_tree(writer, ent->bitmap, t, pos) < 0)
580587
return -1;
581588
}
582589
return 0;

0 commit comments

Comments
 (0)