* [PATCH] rev-list: estimate number of bisection step left
@ 2009-02-17 5:09 Christian Couder
2009-02-17 7:28 ` Junio C Hamano
2009-02-17 14:44 ` Johannes Schindelin
0 siblings, 2 replies; 13+ messages in thread
From: Christian Couder @ 2009-02-17 5:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Ingo Molnar
This patch teaches "git rev-list --bisect-vars" to output an estimate
of the number of bisection step left along with the other variables it
already outputs.
The estimate is calculated using log2(all_revisions_left/2 - 1).
This is the most straightforward formula and seems to work fine in
practice.
We substract 1 to "all_revisions_left/2" because we allready know one
bad revision.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-rev-list.c | 27 +++++++++++++++++++++++++--
git-bisect.sh | 2 +-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 436afa4..ee4abe7 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -574,6 +574,27 @@ static struct commit_list *find_bisection(struct commit_list *list,
return best;
}
+/*
+ * Estimate the number of bisect steps left
+ * Taking log2(all_revisions_left/2 - 1) seems to work fine.
+ * "- 1" is because we already know one bad revision.
+ */
+static int estimate_bisect_steps(int all)
+{
+ int log2 = 0;
+ int left = (all >> 1) - 1;
+
+ if (left <= 0)
+ return 0;
+
+ do {
+ left = left >> 1;
+ log2++;
+ } while (left);
+
+ return log2;
+}
+
int cmd_rev_list(int argc, const char **argv, const char *prefix)
{
struct commit_list *list;
@@ -688,12 +709,14 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
"bisect_nr=%d\n"
"bisect_good=%d\n"
"bisect_bad=%d\n"
- "bisect_all=%d\n",
+ "bisect_all=%d\n"
+ "bisect_steps=%d\n",
hex,
cnt - 1,
all - reaches - 1,
reaches - 1,
- all);
+ all,
+ estimate_bisect_steps(all));
return 0;
}
}
diff --git a/git-bisect.sh b/git-bisect.sh
index 85db4ba..6b23439 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -500,7 +500,7 @@ bisect_next() {
# commit is also a "skip" commit (see above).
exit_if_skipped_commits "$bisect_rev"
- bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this"
+ bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this (roughtly $bisect_steps steps)"
}
bisect_visualize() {
--
1.6.2.rc0.90.g0753.dirty
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 5:09 [PATCH] rev-list: estimate number of bisection step left Christian Couder
@ 2009-02-17 7:28 ` Junio C Hamano
2009-02-19 5:16 ` Christian Couder
2009-02-17 14:44 ` Johannes Schindelin
1 sibling, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2009-02-17 7:28 UTC (permalink / raw)
To: Christian Couder; +Cc: git, Ingo Molnar
Christian Couder <chriscool@tuxfamily.org> writes:
> +static int estimate_bisect_steps(int all)
> +{
> + int log2 = 0;
> + int left = (all >> 1) - 1;
> +
> + if (left <= 0)
> + return 0;
> +
> + do {
> + left = left >> 1;
> + log2++;
> + } while (left);
> +
> + return log2;
> +}
> ...
> diff --git a/git-bisect.sh b/git-bisect.sh
> index 85db4ba..6b23439 100755
> --- a/git-bisect.sh
> +++ b/git-bisect.sh
> @@ -500,7 +500,7 @@ bisect_next() {
> # commit is also a "skip" commit (see above).
> exit_if_skipped_commits "$bisect_rev"
>
> - bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this"
> + bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this (roughtly $bisect_steps steps)"
"roughly".
all left
0 0
1 0
2 0
3 0
4 1
5 1
6 2
7 2
8 2
9 2
It seems that at the very low end the estimate is a bit too optimistic.
How about showing this number from the Porcelain only when $bisect_steps
is more than 2 (or all is more than 9)?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 7:28 ` Junio C Hamano
@ 2009-02-19 5:16 ` Christian Couder
2009-02-19 5:26 ` Christian Couder
2009-02-19 5:32 ` Christian Couder
0 siblings, 2 replies; 13+ messages in thread
From: Christian Couder @ 2009-02-19 5:16 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Ingo Molnar
Le mardi 17 février 2009, Junio C Hamano a écrit :
> Christian Couder <chriscool@tuxfamily.org> writes:
> > +static int estimate_bisect_steps(int all)
> > +{
> > + int log2 = 0;
> > + int left = (all >> 1) - 1;
> > +
> > + if (left <= 0)
> > + return 0;
> > +
> > + do {
> > + left = left >> 1;
> > + log2++;
> > + } while (left);
> > +
> > + return log2;
> > +}
> > ...
> > diff --git a/git-bisect.sh b/git-bisect.sh
> > index 85db4ba..6b23439 100755
> > --- a/git-bisect.sh
> > +++ b/git-bisect.sh
> > @@ -500,7 +500,7 @@ bisect_next() {
> > # commit is also a "skip" commit (see above).
> > exit_if_skipped_commits "$bisect_rev"
> >
> > - bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test
> > after this" + bisect_checkout "$bisect_rev" "$bisect_nr revisions left
> > to test after this (roughtly $bisect_steps steps)"
>
> "roughly".
Yes, thanks.
> all left
> 0 0
> 1 0
> 2 0
> 3 0
> 4 1
> 5 1
> 6 2
> 7 2
> 8 2
> 9 2
>
> It seems that at the very low end the estimate is a bit too optimistic.
> How about showing this number from the Porcelain only when $bisect_steps
> is more than 2 (or all is more than 9)?
I think it's more consistent to always show it.
Now for the algorithm, first please note that we are looking for an estimate
of the number of bisect steps left _after the current one_, and that git
bisect currently only displays an estimate of the number of revisions left
to test _after the current one_.
Here is a table to help analyse what should be the best estimate for
the number of bisect steps left.
N : linear case --> probabilities --> best | v1
------------------------------------------------------------------
1 : G-B --> 0 --> 0 | 0
2 : G-U1-B --> 0 --> 0 | 0
3 : G-U1-U2-B --> 0(1/3) 1(2/3) --> 1 | 0
4 : G-U1-U2-U3-B --> 1 --> 1 | 1
5 : G-U1-U2-U3-U4-B --> 1(3/5) 2(2/5) --> 1 | 1
6 : G-U1-U2-U3-U4-U5-B --> 1(2/6) 2(4/6) --> 2 | 2
7 : G-U1-U2-U3-U4-U5-U6-B --> 1(1/7) 2(6/7) --> 2 | 2
8 : G-U1-U2-U3-U4-U5-U6-U7-B --> 2 --> 2 | 2
9 : G-U1-U2-U3-U4-U5-U6-U7-U8-B --> 2(7/9) 3(2/9) --> 2 | 2
10: G-U1-U2-U3-U4-U5-U6-U7-U8-U9-B --> 2(6/10)3(4/10)--> 2 | 3
In the column "N", there is the number of revisions that could _now_
be the first bad commit we are looking for.
The "linear case" column describes the linear history corresponding to
the number in column N. G means good, B means bad, and Ux means
unknown. Note that the first bad revision we are looking for can be
any Ux or B.
In the "probabilities" column, there are the different outcomes in
number of steps with the odds of each outcome in parenthesis
corresponding to the linear case.
The "best" column gives the most accurate estimate among the different
outcomes in the "probabilities" column.
The "v1" column gives the estimates according my first patch.
Now looking at the table, we have the following:
best(2^n) == n - 1
and for any x between 0 included and 2^n excluded, the probability for
n - 1 steps left looks like:
P(2^n + x) == (2^n - x) / (2^n + x)
If P(2^n + x) < 0.5 we should return n and otherwise n - 1.
But P(2^n + x) < 0.5 means:
2 * (2^n - x) < (2^n + x)
that is: 2^n < 3x
So the improved algorithm could be something like:
static int estimate_bisect_steps(int all)
{
int n, x, e;
float p;
if (all < 3)
return 0;
n = log2(all);
e = exp2(n);
x = all - e;
return (e < 3 * x) ? n : n - 1 ;
}
But on Linux, log2 and exp2 are defined in "math.h" and available with:
_XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99
and we must link with -lm, but I don't know about the other platforms.
So I don't know what to do about them. Please advise.
Thanks in advance,
Christian.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-19 5:16 ` Christian Couder
@ 2009-02-19 5:26 ` Christian Couder
2009-02-19 5:32 ` Christian Couder
1 sibling, 0 replies; 13+ messages in thread
From: Christian Couder @ 2009-02-19 5:26 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Ingo Molnar, Johannes Schindelin, John Tapsell, Thomas Rast
Le jeudi 19 février 2009, Christian Couder a écrit :
> So the improved algorithm could be something like:
>
> static int estimate_bisect_steps(int all)
> {
> int n, x, e;
> float p;
Oops, the line above is not needed.
> if (all < 3)
> return 0;
>
> n = log2(all);
> e = exp2(n);
> x = all - e;
>
> return (e < 3 * x) ? n : n - 1 ;
> }
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-19 5:16 ` Christian Couder
2009-02-19 5:26 ` Christian Couder
@ 2009-02-19 5:32 ` Christian Couder
2009-02-19 6:02 ` John Tapsell
1 sibling, 1 reply; 13+ messages in thread
From: Christian Couder @ 2009-02-19 5:32 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Ingo Molnar, Johannes Schindelin, John Tapsell, Thomas Rast
Le jeudi 19 février 2009, Christian Couder a écrit :
>
> But on Linux, log2 and exp2 are defined in "math.h" and available with:
>
> _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99
>
> and we must link with -lm, but I don't know about the other platforms.
>
> So I don't know what to do about them. Please advise.
What I mean is that log2 is just something like:
int log2 = 0;
for (; n > 1; n >>= 1)
log2++;
and exp2 is just "1 << n", so I wonder if it's really necessary to add a lot
of stuff in the Makefile for these 2 really short functions.
Regards,
Christian.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-19 5:32 ` Christian Couder
@ 2009-02-19 6:02 ` John Tapsell
2009-02-19 6:49 ` Christian Couder
0 siblings, 1 reply; 13+ messages in thread
From: John Tapsell @ 2009-02-19 6:02 UTC (permalink / raw)
To: Christian Couder
Cc: Junio C Hamano, git, Ingo Molnar, Johannes Schindelin,
Thomas Rast
2009/2/19 Christian Couder <chriscool@tuxfamily.org>:
> Le jeudi 19 février 2009, Christian Couder a écrit :
>>
>> But on Linux, log2 and exp2 are defined in "math.h" and available with:
log2 in math.h is for doubles, when we only want an integer answer.
There's no need for math.h here.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-19 6:02 ` John Tapsell
@ 2009-02-19 6:49 ` Christian Couder
0 siblings, 0 replies; 13+ messages in thread
From: Christian Couder @ 2009-02-19 6:49 UTC (permalink / raw)
To: John Tapsell
Cc: Junio C Hamano, git, Ingo Molnar, Johannes Schindelin,
Thomas Rast
Le jeudi 19 février 2009, John Tapsell a écrit :
> 2009/2/19 Christian Couder <chriscool@tuxfamily.org>:
> > Le jeudi 19 février 2009, Christian Couder a écrit :
> >> But on Linux, log2 and exp2 are defined in "math.h" and available
> >> with:
>
> log2 in math.h is for doubles, when we only want an integer answer.
> There's no need for math.h here.
Yeah, you are right. Sorry about the noise. I will send a patch soon.
Thanks,
Christian.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 5:09 [PATCH] rev-list: estimate number of bisection step left Christian Couder
2009-02-17 7:28 ` Junio C Hamano
@ 2009-02-17 14:44 ` Johannes Schindelin
2009-02-17 15:11 ` John Tapsell
1 sibling, 1 reply; 13+ messages in thread
From: Johannes Schindelin @ 2009-02-17 14:44 UTC (permalink / raw)
To: Christian Couder; +Cc: Junio C Hamano, git, Ingo Molnar
Hi,
On Tue, 17 Feb 2009, Christian Couder wrote:
> +static int estimate_bisect_steps(int all)
> +{
> + int log2 = 0;
> + int left = (all >> 1) - 1;
> +
> + if (left <= 0)
> + return 0;
> +
> + do {
> + left = left >> 1;
> + log2++;
> + } while (left);
> +
> + return log2;
> +}
How about this instead, calling it from cmd_rev_list directly?
static int log2(int n)
{
int log2;
for (log2 = 0; n > 1; log2++)
n >>= 1;
return log2;
}
Ciao,
Dscho
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 14:44 ` Johannes Schindelin
@ 2009-02-17 15:11 ` John Tapsell
2009-02-17 15:31 ` Johannes Schindelin
0 siblings, 1 reply; 13+ messages in thread
From: John Tapsell @ 2009-02-17 15:11 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Christian Couder, Junio C Hamano, git, Ingo Molnar
2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
> Hi,
>
> On Tue, 17 Feb 2009, Christian Couder wrote:
>
>> +static int estimate_bisect_steps(int all)
>> +{
>> + int log2 = 0;
>> + int left = (all >> 1) - 1;
>> +
>> + if (left <= 0)
>> + return 0;
>> +
>> + do {
>> + left = left >> 1;
>> + log2++;
>> + } while (left);
>> +
>> + return log2;
>> +}
>
> How about this instead, calling it from cmd_rev_list directly?
>
> static int log2(int n)
> {
> int log2;
>
> for (log2 = 0; n > 1; log2++)
> n >>= 1;
>
> return log2;
> }
This would work, if you want a non-iterative solution
unsigned int log2_integer_approximate(unsigned int n){
*((float*)&n) = (float)n;
return ((n & (~((1<<23) - 1))) >> 23) - 127;
}
(It's correct up to 2^25, then it's off by 1 for a few.)
> Ciao,
> Dscho
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 15:11 ` John Tapsell
@ 2009-02-17 15:31 ` Johannes Schindelin
2009-02-17 15:36 ` John Tapsell
2009-02-17 15:39 ` Thomas Rast
0 siblings, 2 replies; 13+ messages in thread
From: Johannes Schindelin @ 2009-02-17 15:31 UTC (permalink / raw)
To: John Tapsell; +Cc: Christian Couder, Junio C Hamano, git, Ingo Molnar
Hi,
On Tue, 17 Feb 2009, John Tapsell wrote:
> 2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
>
> > On Tue, 17 Feb 2009, Christian Couder wrote:
> >
> >> +static int estimate_bisect_steps(int all)
> >> +{
> >> + int log2 = 0;
> >> + int left = (all >> 1) - 1;
> >> +
> >> + if (left <= 0)
> >> + return 0;
> >> +
> >> + do {
> >> + left = left >> 1;
> >> + log2++;
> >> + } while (left);
> >> +
> >> + return log2;
> >> +}
> >
> > How about this instead, calling it from cmd_rev_list directly?
> >
> > static int log2(int n)
> > {
> > int log2;
> >
> > for (log2 = 0; n > 1; log2++)
> > n >>= 1;
> >
> > return log2;
> > }
>
> This would work, if you want a non-iterative solution
>
> unsigned int log2_integer_approximate(unsigned int n){
> *((float*)&n) = (float)n;
> return ((n & (~((1<<23) - 1))) >> 23) - 127;
> }
That assumes that your floats are IEEE floats, right?
Ciao,
Dscho
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 15:31 ` Johannes Schindelin
@ 2009-02-17 15:36 ` John Tapsell
2009-02-17 15:39 ` Johannes Schindelin
2009-02-17 15:39 ` Thomas Rast
1 sibling, 1 reply; 13+ messages in thread
From: John Tapsell @ 2009-02-17 15:36 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Christian Couder, Junio C Hamano, git, Ingo Molnar
2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
> Hi,
>
> On Tue, 17 Feb 2009, John Tapsell wrote:
>
>> 2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
>>
>> > On Tue, 17 Feb 2009, Christian Couder wrote:
>> >
>> >> +static int estimate_bisect_steps(int all)
>> >> +{
>> >> + int log2 = 0;
>> >> + int left = (all >> 1) - 1;
>> >> +
>> >> + if (left <= 0)
>> >> + return 0;
>> >> +
>> >> + do {
>> >> + left = left >> 1;
>> >> + log2++;
>> >> + } while (left);
>> >> +
>> >> + return log2;
>> >> +}
>> >
>> > How about this instead, calling it from cmd_rev_list directly?
>> >
>> > static int log2(int n)
>> > {
>> > int log2;
>> >
>> > for (log2 = 0; n > 1; log2++)
>> > n >>= 1;
>> >
>> > return log2;
>> > }
>>
>> This would work, if you want a non-iterative solution
>>
>> unsigned int log2_integer_approximate(unsigned int n){
>> *((float*)&n) = (float)n;
>> return ((n & (~((1<<23) - 1))) >> 23) - 127;
>> }
>
> That assumes that your floats are IEEE floats, right?
Yeah. Is it a bad assumption? Does git run on any system in which they aren't?
>
> Ciao,
> Dscho
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 15:36 ` John Tapsell
@ 2009-02-17 15:39 ` Johannes Schindelin
0 siblings, 0 replies; 13+ messages in thread
From: Johannes Schindelin @ 2009-02-17 15:39 UTC (permalink / raw)
To: John Tapsell; +Cc: Christian Couder, Junio C Hamano, git, Ingo Molnar
Hi,
On Tue, 17 Feb 2009, John Tapsell wrote:
> 2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
>
> > On Tue, 17 Feb 2009, John Tapsell wrote:
> >
> >> 2009/2/17 Johannes Schindelin <Johannes.Schindelin@gmx.de>:
> >>
> >> > On Tue, 17 Feb 2009, Christian Couder wrote:
> >> >
> >> >> +static int estimate_bisect_steps(int all)
> >> >> +{
> >> >> + int log2 = 0;
> >> >> + int left = (all >> 1) - 1;
> >> >> +
> >> >> + if (left <= 0)
> >> >> + return 0;
> >> >> +
> >> >> + do {
> >> >> + left = left >> 1;
> >> >> + log2++;
> >> >> + } while (left);
> >> >> +
> >> >> + return log2;
> >> >> +}
> >> >
> >> > How about this instead, calling it from cmd_rev_list directly?
> >> >
> >> > static int log2(int n)
> >> > {
> >> > int log2;
> >> >
> >> > for (log2 = 0; n > 1; log2++)
> >> > n >>= 1;
> >> >
> >> > return log2;
> >> > }
> >>
> >> This would work, if you want a non-iterative solution
> >>
> >> unsigned int log2_integer_approximate(unsigned int n){
> >> *((float*)&n) = (float)n;
> >> return ((n & (~((1<<23) - 1))) >> 23) - 127;
> >> }
> >
> > That assumes that your floats are IEEE floats, right?
>
> Yeah. Is it a bad assumption? Does git run on any system in which they
> aren't?
Only when you are porting Git to embedded devices.
Don't moan: there exists a git-daemon for iPhone. Oh, wait! /me
scribbles that down for the UGFWIINI contest.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] rev-list: estimate number of bisection step left
2009-02-17 15:31 ` Johannes Schindelin
2009-02-17 15:36 ` John Tapsell
@ 2009-02-17 15:39 ` Thomas Rast
1 sibling, 0 replies; 13+ messages in thread
From: Thomas Rast @ 2009-02-17 15:39 UTC (permalink / raw)
To: Johannes Schindelin
Cc: John Tapsell, Christian Couder, Junio C Hamano, git, Ingo Molnar
[-- Attachment #1: Type: text/plain, Size: 300 bytes --]
Johannes Schindelin wrote:
> > unsigned int log2_integer_approximate(unsigned int n){
[...]
> That assumes that your floats are IEEE floats, right?
For extra weird code, you could the standard 5-line bit order inverter
and apply ffs().
;-)
--
Thomas Rast
trast@{inf,student}.ethz.ch
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-02-19 6:51 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-17 5:09 [PATCH] rev-list: estimate number of bisection step left Christian Couder
2009-02-17 7:28 ` Junio C Hamano
2009-02-19 5:16 ` Christian Couder
2009-02-19 5:26 ` Christian Couder
2009-02-19 5:32 ` Christian Couder
2009-02-19 6:02 ` John Tapsell
2009-02-19 6:49 ` Christian Couder
2009-02-17 14:44 ` Johannes Schindelin
2009-02-17 15:11 ` John Tapsell
2009-02-17 15:31 ` Johannes Schindelin
2009-02-17 15:36 ` John Tapsell
2009-02-17 15:39 ` Johannes Schindelin
2009-02-17 15:39 ` Thomas Rast
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 NNTP newsgroup(s).