对于随机访问迭代器,GCC find / find_if重载的用途是什么?

时间:2014-06-18 22:25:03

标签: c++ gcc

我在查看<algorithm>实现时找到了这个代码段:

/**
*  @if maint
*  This is an overload used by find() for the RAI case.
*  @endif
*/
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;
}
}

根据我的理解,此处唯一的“技巧”是使用distance / 4执行if(...) return; ++次迭代,并使用distance % 4内的其余switch次项进行迭代。正如预期的那样,执行完全相同数量的比较和增量,并且理论复杂性是相同的。它是如何比简单的输入迭代器实现更好的优化?它是一种微优化,可以降低循环迭代的次数,还是有更聪明的东西我没有得到?

1 个答案:

答案 0 :(得分:3)

这种技术称为loop unrolling,以避免在每次迭代时通过权衡二进制大小(和空间)来检查条件的成本。

加速也取决于你的体系结构,但通常super-scalar cpu可以通过打破可能在缓存丢失时阻止你的cpu的潜在危险的依赖链来利用它。

虽然理论复杂度是相同的(如果你考虑比较主导操作),算法(在我描述的cpu上)可以显着更快地执行。就复杂性约束而言,任何STL库都可以实现自己的版本。

相关答案: When, if ever, is loop unrolling still useful?