Imagine that you have found a kernel bug, but you have no idea which of the thousand or more patches included in the tree that you are testing might have caused it to appear. In principle, you could revert the patches one by one and test the kernel after reverting each of them, but that would take way too much time. The solution is to use binary searching, also known as bisection.
To explain what it is we first assume that the kernel does not work for you any
more after you have applied a series of
patches (
may be of the order of
1000). We also assume that it takes
minutes on the average to
compile and run the kernel on your system after reverting one patch (
may be of the order of 10). Under these assumptions, if you tried to revert
patches one by one and test the kernel each time, you could spend about
minutes worst-case before finding the offending patch. Of
course, you might be lucky and the bug might have been introduced by the last
patch in the series, but generally this is not very probable. More precisely,
if you know nothing about the patches in question, you should assume that each
of them is equally likely to have introduced the bug and therefore the
probability of the bug being introduced by a specific patch is equal to
(hence, the worst case is not very probable either, but that does not improve
the situation very much).
Naturally, you can revert
patches out of
and then test the kernel to see
whether or not one of these
patches has introduced the bug. Still, the
question arises what number
should be equal to. To answer it, let's
estimate the maximum expected time needed to find the patch that has introduced
the bug under the assumption that
patches are reverted in the first step.
For this purpose, let
denote the event that one of the
patches
reverted in the first step has introduced the bug and let
denote the
event that the bug has been introduced by one of the remaining
patches.
If
occurs, the time needed to find the buggy patch will not be greater
than
(we need to search a series of
patches and
it takes
minutes to check one patch on the average) and the
probability of occurrence of
is
. In turn, if
occurs, the time needed to find the buggy patch will not be greater than
and the probability of occurrence of
is
. Hence, since
and
are mutually exclusive and
one of them must occur, the maximum average time needed to find the buggy patch
is given by
Further, if the kernel still doesn't work after reverting
patches from the
series, we get the problem that is formally equivalent to the initial one with
the number of patches to search reduced by half. Then, we can repeat the
above reasoning for
and it will turn out that the most reasonable
thing we can do is to revert
patches and test the kernel.
On the other hand, if the kernel works after we have reverted
patches from
the series, we need to reapply some of the reverted patches and test it once
again. In that case, however, we still have
patches to check and a
reasoning analogous to the above one leads to the conclusion that the most
reasonable number of patches to reapply before testing the kernel once again is
.
Thus we can establish a procedure, referred to as bisection or binary searching,
allowing us to reduce the number of patches to check by half in every step.
Namely, if the initial number of patches to check is
, we revert
patches and test the kernel. Next, depending on the result of the
previous test, we either revert or reapply
patches and test the kernel
once again. Subsequently, depending on the result of the previous test, we
either revert or reapply
patches and test the kernel once again. By
repeating this approximately
times we can reduce the number of
suspicious patches to one and thus find the patch that has introduced the bug.
It is not very difficult to observe that the average time needed to find the
buggy patch this way is proportional to
.