2013-02-18 4 views
5

Я случайно столкнулся с источником std::find и считаю это сбивающим с толку. В основном он делит количество элементов на 4 и сделайте сравнение 4 в каждом раунде:Почему std :: find реализован таким образом?

template<typename _RandomAccessIterator, typename _Tp> 
_RandomAccessIterator 
__find(_RandomAccessIterator __first, _RandomAccessIterator __last, 
    const _Tp& __val, random_access_iterator_tag) 
{ 
    typename iterator_traits<_RandomAccessIterator>::difference_type 
__trip_count = (__last - __first) >> 2; 

    for (; __trip_count > 0; --__trip_count) 
{ 
    if (*__first == __val) 
    return __first; 
    ++__first; 

    if (*__first == __val) 
    return __first; 
    ++__first; 

    if (*__first == __val) 
    return __first; 
    ++__first; 

    if (*__first == __val) 
    return __first; 
    ++__first; 
} 

    switch (__last - __first) 
{ 
case 3: 
    if (*__first == __val) 
    return __first; 
    ++__first; 
case 2: 
    if (*__first == __val) 
    return __first; 
    ++__first; 
case 1: 
    if (*__first == __val) 
    return __first; 
    ++__first; 
case 0: 
default: 
    return __last; 
} 
} 

Я понятия не имею, почему это делается таким образом. Похоже на некоторую оптимизацию. Но я не думаю, что это будет легко использовать многоядерные процессоры. Это в любом случае.

Любые идеи?

+4

Похоже ручного разворачивания цикла. Откуда эта реализация? –

+0

Во-первых, он тратит меньше времени на сравнение «__trip_count» с нолем и больше времени, фактически сравнивая значения. –

ответ

4

Это петля для разворота. Результат тот же, но он более дружелюбен для процессора.

Асимптотическая сложность такая же.

-2

Это Duff's device. Это старая техника оптимизации , которая смешивает в то время как и переключает заявления особым образом. Он использует разворот цикла. В ассемблере вы прыгаете прямо в развернутом цикле.

+5

Это не устройство Даффа, оператор switch не находится внутри цикла. Вполне возможно, что испущенный код был бы меньшим, если бы он использовал устройство Даффа. –

+0

Хорошо, моя ошибка. Я недостаточно читал код. –

+0

@SteveJessop: У меня создалось впечатление, что вы положили устройство Duff в конец развернутой петли не внутри нее. Только последняя итерация будет иметь не полный подсчет. –

Смежные вопросы