git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/1] commit-reach: fix first-parent heuristic
@ 2018-10-18 17:24 Derrick Stolee via GitGitGadget
  2018-10-18 17:24 ` [PATCH 1/1] " Derrick Stolee via GitGitGadget
  2018-10-19  2:31 ` [PATCH 0/1] " Junio C Hamano
  0 siblings, 2 replies; 7+ messages in thread
From: Derrick Stolee via GitGitGadget @ 2018-10-18 17:24 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

I originally reported this fix [1] after playing around with the trace2
series for measuring performance. Since trace2 isn't merging quickly, I
pulled the performance fix patch out and am sending it on its own. The only
difference here is that we don't have the tracing to verify the performance
fix in the test script.

See the patch message for details about the fix.

Thanks, -Stolee

[1] 
https://public-inbox.org/git/20180906151309.66712-7-dstolee@microsoft.com/

[RFC PATCH 6/6] commit-reach: fix first-parent heuristic

Derrick Stolee (1):
  commit-reach: fix first-parent heuristic

 commit-reach.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)


base-commit: a4b8ab5363a32f283a61ef3a962853556d136c0e
Published-As: https://github.com/gitgitgadget/git/releases/tags/pr-51%2Fderrickstolee%2Ffirst-parent-heuristic-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-51/derrickstolee/first-parent-heuristic-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/51
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/1] commit-reach: fix first-parent heuristic
  2018-10-18 17:24 [PATCH 0/1] commit-reach: fix first-parent heuristic Derrick Stolee via GitGitGadget
@ 2018-10-18 17:24 ` Derrick Stolee via GitGitGadget
  2018-10-19  5:24   ` Junio C Hamano
  2018-10-19  2:31 ` [PATCH 0/1] " Junio C Hamano
  1 sibling, 1 reply; 7+ messages in thread
From: Derrick Stolee via GitGitGadget @ 2018-10-18 17:24 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Derrick Stolee

From: Derrick Stolee <dstolee@microsoft.com>

The algorithm in can_all_from_reach_with_flags() performs a depth-
first-search, terminated by generation number, intending to use
a hueristic that "important" commits are found in the first-parent
history. This heuristic is valuable in scenarios like fetch
negotiation.

However, there is a problem! After the search finds a target commit,
it should pop all commits off the stack and mark them as "can reach".
This logic is incorrect, so the algorithm instead walks all reachable
commits above the generation-number cutoff.

The existing algorithm is still an improvement over the previous
algorithm, as the worst-case complexity went from quadratic to linear.
The performance measurement at the time was good, but not dramatic.
By fixing this heuristic, we reduce the number of walked commits.

We can also re-run the performance tests from commit 4fbcca4e
"commit-reach: make can_all_from_reach... linear".

Performance was measured on the Linux repository using
'test-tool reach can_all_from_reach'. The input included rows seeded by
tag values. The "small" case included X-rows as v4.[0-9]* and Y-rows as
v3.[0-9]*. This mimics a (very large) fetch that says "I have all major
v3 releases and want all major v4 releases." The "large" case included
X-rows as "v4.*" and Y-rows as "v3.*". This adds all release-candidate
tags to the set, which does not greatly increase the number of objects
that are considered, but does increase the number of 'from' commits,
demonstrating the quadratic nature of the previous code.

Small Case:

4fbcca4e~1: 0.85 s
  4fbcca4e: 0.26 s (num_walked: 1,011,035)
      HEAD: 0.14 s (num_walked:     8,601)

Large Case:

4fbcca4e~1: 24.0  s
  4fbcca4e:  0.12 s (num_walked:  503,925)
      HEAD:  0.06 s (num_walked:  217,243)

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 commit-reach.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/commit-reach.c b/commit-reach.c
index 9f79ce0a22..79419be8af 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -593,8 +593,10 @@ int can_all_from_reach_with_flag(struct object_array *from,
 		while (stack) {
 			struct commit_list *parent;
 
-			if (stack->item->object.flags & with_flag) {
+			if (stack->item->object.flags & (with_flag | RESULT)) {
 				pop_commit(&stack);
+				if (stack)
+					stack->item->object.flags |= RESULT;
 				continue;
 			}
 
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/1] commit-reach: fix first-parent heuristic
  2018-10-18 17:24 [PATCH 0/1] commit-reach: fix first-parent heuristic Derrick Stolee via GitGitGadget
  2018-10-18 17:24 ` [PATCH 1/1] " Derrick Stolee via GitGitGadget
@ 2018-10-19  2:31 ` Junio C Hamano
  2018-10-19 19:40   ` Jeff Hostetler
  1 sibling, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2018-10-19  2:31 UTC (permalink / raw)
  To: Derrick Stolee via GitGitGadget; +Cc: git

"Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:

> I originally reported this fix [1] after playing around with the trace2
> series for measuring performance. Since trace2 isn't merging quickly, I
> pulled the performance fix patch out and am sending it on its own. The only
> difference here is that we don't have the tracing to verify the performance
> fix in the test script.

Thanks for sending this separately.  What's the current status of
the tracing patch series, by the way?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] commit-reach: fix first-parent heuristic
  2018-10-18 17:24 ` [PATCH 1/1] " Derrick Stolee via GitGitGadget
@ 2018-10-19  5:24   ` Junio C Hamano
  2018-10-19 12:32     ` Derrick Stolee
  0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2018-10-19  5:24 UTC (permalink / raw)
  To: Derrick Stolee via GitGitGadget; +Cc: git, Derrick Stolee

"Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:

> We can also re-run the performance tests from commit 4fbcca4e
> "commit-reach: make can_all_from_reach... linear".
>
> Performance was measured on the Linux repository using
> 'test-tool reach can_all_from_reach'. The input included rows seeded by
> tag values. The "small" case included X-rows as v4.[0-9]* and Y-rows as
> v3.[0-9]*. This mimics a (very large) fetch that says "I have all major
> v3 releases and want all major v4 releases." The "large" case included
> X-rows as "v4.*" and Y-rows as "v3.*". This adds all release-candidate
> tags to the set, which does not greatly increase the number of objects
> that are considered, but does increase the number of 'from' commits,
> demonstrating the quadratic nature of the previous code.

These micro-benchmarks are interesting, but we should also remember
to describe the impact of the bug being fixed in the larger picture.
What end-user visible operations are affected?  Computing merge-base?
Finding if a push fast-forwards?  Something else?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] commit-reach: fix first-parent heuristic
  2018-10-19  5:24   ` Junio C Hamano
@ 2018-10-19 12:32     ` Derrick Stolee
  2018-10-22  2:29       ` Junio C Hamano
  0 siblings, 1 reply; 7+ messages in thread
From: Derrick Stolee @ 2018-10-19 12:32 UTC (permalink / raw)
  To: Junio C Hamano, Derrick Stolee via GitGitGadget; +Cc: git, Derrick Stolee

On 10/19/2018 1:24 AM, Junio C Hamano wrote:
> "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> We can also re-run the performance tests from commit 4fbcca4e
>> "commit-reach: make can_all_from_reach... linear".
>>
>> Performance was measured on the Linux repository using
>> 'test-tool reach can_all_from_reach'. The input included rows seeded by
>> tag values. The "small" case included X-rows as v4.[0-9]* and Y-rows as
>> v3.[0-9]*. This mimics a (very large) fetch that says "I have all major
>> v3 releases and want all major v4 releases." The "large" case included
>> X-rows as "v4.*" and Y-rows as "v3.*". This adds all release-candidate
>> tags to the set, which does not greatly increase the number of objects
>> that are considered, but does increase the number of 'from' commits,
>> demonstrating the quadratic nature of the previous code.
> These micro-benchmarks are interesting, but we should also remember
> to describe the impact of the bug being fixed in the larger picture.
> What end-user visible operations are affected?  Computing merge-base?
> Finding if a push fast-forwards?  Something else?

Sorry about that. Here is a description that could be inserted into the 
commit message:

The can_all_from_reach() method synthesizes the logic for one iteration 
of can_all_from_reach_with_flags() which is used by the server during 
fetch negotiation to determine if more haves/wants are needed. The logic 
is also used by is_descendant_of() which is used to check if a 
force-push is required and in 'git branch --contains'.

Thanks,
-Stolee

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/1] commit-reach: fix first-parent heuristic
  2018-10-19  2:31 ` [PATCH 0/1] " Junio C Hamano
@ 2018-10-19 19:40   ` Jeff Hostetler
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Hostetler @ 2018-10-19 19:40 UTC (permalink / raw)
  To: Junio C Hamano, Derrick Stolee via GitGitGadget; +Cc: git



On 10/18/2018 10:31 PM, Junio C Hamano wrote:
> "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
>> I originally reported this fix [1] after playing around with the trace2
>> series for measuring performance. Since trace2 isn't merging quickly, I
>> pulled the performance fix patch out and am sending it on its own. The only
>> difference here is that we don't have the tracing to verify the performance
>> fix in the test script.
> 
> Thanks for sending this separately.  What's the current status of
> the tracing patch series, by the way?
> 

I'm still working on it. I hope to reroll and submit a new version
next week.  We are currently dogfooding a version of it with our gvfs
users.

Jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] commit-reach: fix first-parent heuristic
  2018-10-19 12:32     ` Derrick Stolee
@ 2018-10-22  2:29       ` Junio C Hamano
  0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2018-10-22  2:29 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: Derrick Stolee via GitGitGadget, git, Derrick Stolee

Derrick Stolee <stolee@gmail.com> writes:

> On 10/19/2018 1:24 AM, Junio C Hamano wrote:
>> "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
>>
>>> We can also re-run the performance tests from commit 4fbcca4e
>>> "commit-reach: make can_all_from_reach... linear".
>>>
>>> Performance was measured on the Linux repository using
>>> 'test-tool reach can_all_from_reach'. The input included rows seeded by
>>> tag values. The "small" case included X-rows as v4.[0-9]* and Y-rows as
>>> v3.[0-9]*. This mimics a (very large) fetch that says "I have all major
>>> v3 releases and want all major v4 releases." The "large" case included
>>> X-rows as "v4.*" and Y-rows as "v3.*". This adds all release-candidate
>>> tags to the set, which does not greatly increase the number of objects
>>> that are considered, but does increase the number of 'from' commits,
>>> demonstrating the quadratic nature of the previous code.
>> These micro-benchmarks are interesting, but we should also remember
>> to describe the impact of the bug being fixed in the larger picture.
>> What end-user visible operations are affected?  Computing merge-base?
>> Finding if a push fast-forwards?  Something else?
>
> Sorry about that. Here is a description that could be inserted into
> the commit message:
>
> The can_all_from_reach() method synthesizes the logic for one
> iteration of can_all_from_reach_with_flags() which is used by the
> server during fetch negotiation to determine if more haves/wants are
> needed. The logic is also used by is_descendant_of() which is used to
> check if a force-push is required and in 'git branch --contains'.

I am afraid that it is still not end-user serving enough.  The level
of "larger picture" I had in mind was those that would appear as an
entry in the release notes, e.g. (this is for illustration purposes
only; I do not claim its actual contents is correct).

	We started using commit generation numbers in various
	reachability computations, but due to a bug, negitiation
	between the "git fetch" and the server started to require
	30% more roundtrips than necessary, and it has become less
	efficient to see if a commit is a descendant of another
	commit in certain cases, which has been corrected in this
	release.

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-10-22  2:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-18 17:24 [PATCH 0/1] commit-reach: fix first-parent heuristic Derrick Stolee via GitGitGadget
2018-10-18 17:24 ` [PATCH 1/1] " Derrick Stolee via GitGitGadget
2018-10-19  5:24   ` Junio C Hamano
2018-10-19 12:32     ` Derrick Stolee
2018-10-22  2:29       ` Junio C Hamano
2018-10-19  2:31 ` [PATCH 0/1] " Junio C Hamano
2018-10-19 19:40   ` Jeff Hostetler

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).