[lld] r284594 - Add a faster binary search.

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 21 09:13:56 PDT 2016


It looks like libstdc++ uses a branch in the loop, this implementation
uses a single conditional move and always reduces size conservatively
by the same amount.

The theory in http://cglab.ca/~morin/misc/arraylayout-v2/ is that it
is more branch prediction friendly. I got very modest speed ups on top
of trunk with it. Experimenting with disabling the offset map shows
that it is indeed quite a bit faster. When linking firefox's XUL
std::upper_bound causes lld to be 5% slower.

Cheers,
Rafael


On 19 October 2016 at 14:27, Rui Ueyama <ruiu at google.com> wrote:
> This seems pretty straightforward binary search, so I'm wondering why
> std::upper_bound is so slow. Just curious.
>
> On Wed, Oct 19, 2016 at 11:23 AM, Rafael Avila de Espindola
> <rafael.espindola at gmail.com> wrote:
>>
>> Same semantics, but a faster implementation.
>>
>>
>> On October 19, 2016 1:58:14 PM EDT, Rui Ueyama <ruiu at google.com> wrote:
>>>
>>> This seems a binary search, so how it is different from std::upper_bound?
>>>
>>> On Wed, Oct 19, 2016 at 7:17 AM, Rafael Espindola via llvm-commits
>>> <llvm-commits at lists.llvm.org> wrote:
>>>>
>>>> Author: rafael
>>>> Date: Wed Oct 19 09:17:36 2016
>>>> New Revision: 284594
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=284594&view=rev
>>>> Log:
>>>> Add a faster binary search.
>>>>
>>>> Even with the hash table cache, binary search was still pretty
>>>> hot. This can be made even faster with prefetching.
>>>>
>>>> Idea from http://cglab.ca/~morin/misc/arraylayout-v2/
>>>>
>>>> I will suggest moving this to llvm.
>>>>
>>>> Modified:
>>>>     lld/trunk/ELF/InputSection.cpp
>>>>
>>>> Modified: lld/trunk/ELF/InputSection.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=284594&r1=284593&r2=284594&view=diff
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/ELF/InputSection.cpp (original)
>>>> +++ lld/trunk/ELF/InputSection.cpp Wed Oct 19 09:17:36 2016
>>>> @@ -651,6 +651,19 @@ SectionPiece *MergeInputSection<ELFT>::g
>>>>    return const_cast<SectionPiece *>(This->getSectionPiece(Offset));
>>>>  }
>>>>
>>>> +template <class It, class T, class Compare>
>>>> +static It fastUpperBound(It First, It Last, const T &Value, Compare
>>>> Comp) {
>>>> +  size_t Size = std::distance(First, Last);
>>>> +  assert(Size != 0);
>>>> +  while (Size != 1) {
>>>> +    size_t H = Size / 2;
>>>> +    const It MI = First + H;
>>>> +    Size -= H;
>>>> +    First = Comp(Value, *MI) ? First : First + H;
>>>> +  }
>>>> +  return Comp(Value, *First) ? First : First + 1;
>>>> +}
>>>> +
>>>>  template <class ELFT>
>>>>  const SectionPiece *
>>>>  MergeInputSection<ELFT>::getSectionPiece(uintX_t Offset) const {
>>>> @@ -659,7 +672,7 @@ MergeInputSection<ELFT>::getSectionPiece
>>>>      fatal(getName(this) + ": entry is past the end of the section");
>>>>
>>>>    // Find the element this offset points to.
>>>> -  auto I = std::upper_bound(
>>>> +  auto I = fastUpperBound(
>>>>        Pieces.begin(), Pieces.end(), Offset,
>>>>        [](const uintX_t &A, const SectionPiece &B) { return A <
>>>> B.InputOff; });
>>>>    --I;
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>>
>>
>> --
>> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>
>


More information about the llvm-commits mailing list