0

Folowing snippet is from OpenCV find_obj.cpp which is demo for using SURF,


double
compareSURFDescriptors( const float* d1, const float* d2, double best, int length )
{
    double total_cost = 0;
    assert( length % 4 == 0 );
    int i;
    for( i = 0; i  best )
            break;
    }
    return total_cost;
}


As far as I can tell it checking the euclidian distance, what I do not understand is why is it doing it in groups of 4? Why not calculate the whole thing at once?

4

2 に答える 2

3

通常、このようなことは、SSE の最適化を可能にするために行われます。SSE レジスタは 128 ビット長で、4 つの float を格納できるため、1 つの命令を使用して 4 つの減算を並列に実行できます。

もう 1 つの利点: ループ カウンターを確認する必要があるのは、4 回ごとの違いの後でのみです。これにより、コンパイラが SSE コードを生成する機会を利用しなくても、コードが高速になります。たとえば、VS2008 では、-O2 を使用しても、そうではありませんでした。

    
      double t0 = d1[i] - d2[i];
00D91666 fld dword ptr [edx-0Ch]
00D91669 fsub dword ptr [ecx-4]
        double t1 = d1[i+1] - d2[i+1];
00D9166C fld dword ptr [ebx+ecx]
00D9166F fsub dword ptr [ecx]
        double t2 = d1[i+2] - d2[i+2];
00D91671 fld dword ptr [edx-4]
00D91674 fsub dword ptr [ecx+4]
        double t3 = d1[i+3] - d2[i+3];
00D91677 fld dword ptr [edx]
00D91679 fsub dword ptr [ecx+8]
        総コスト += t0*t0 + t1*t1 + t2*t2 + t3*t3;
00D9167C フィールド st(2)
00D9167E fmulp st(3),st
00D91680 fld st(3)
00D91682 fmulp st(4),st
00D91684 fxch st(2)
00D91686 faddp st(3),st
00D91688 fmul st(0),st
00D9168A faddp st(2),st
00D9168C fmul st(0),st
00D9168E faddp st(1),st
00D91690 faddp st(2),st
于 2011-02-14T12:50:56.940 に答える
1

それは、サブリージョンごとに 4 つの数字が得られるためだと思います。全部で 4x4x4 の部分領域で 64 の長さのベクトルになります。したがって、基本的には2つのサブリージョン間の違いが得られます。

于 2011-02-08T20:27:25.303 に答える