2013-02-18 9 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; 
} 
} 

なぜこのように行われたのかわかりません。いくつかの最適化のように見えます。しかし、私はこれがマルチコアを簡単に利用できるとは思わない。これはとにかく1つのスレッドにあります。

アイデア?

+4

手動ループのアンローリングのようです。この実装はいつですか? –

+0

一方、 '__trip_count'とゼロを比較する時間が少なく、実際に値を比較する時間が長くなります。 –

答えて

7

loop unwinding(ループアンローリングとも呼ばれます)のように見えます。

4

ループアンローリングです。結果は同じですが、プロセッサにとってはより親切です。

しかし、漸近的複雑さは同じです。

-2

これはDuff's deviceです。それは古い最適化技術 であり、whileとswitch文を特別な方法で組み合わせています。ループのアンロールが使用されます。アセンブラでは、アンロールされたループの中ですぐにジャンプします。

+5

Duffのデバイスではないため、switchステートメントはループ内にありません。しかし、Duffのデバイスを使用した場合、放出されるコードはもっと小さくなる可能性があります。 –

+0

私のせいです。私は十分注意深いコードを読まなかった。 –

+0

@SteveJessop:私はダフのデバイスをその中に入っていないループの終わりに置いたという印象を受けました。最後の反復だけが完全でないカウントを持つことになります。 –

関連する問題