1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// MatchImpl.cpp: implementation of the CMatchImpl class.
//
//////////////////////////////////////////////////////////////////////
 
#include "stdafx.h"
#include "MatchImpl.h"
#include "SISMath.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <emmintrin.h>
//#include <tmmintrin.h>
//#include <ia32intrin.h>
#include <math.h>
 
//#define MOSIS_ASM
 
extern "C"{
    int64 _asm_GetCC_8u(const uchar * vec1, const uchar * vec2, int len, int flag);// 0= aa, 1=au, 2=uu
};
 
 
 
int64    CSISMath::Get_CCU8_A(const uchar * vec1, const uchar * vec2, int len )
{
#if defined(MOSIS_ASM)
    return _asm_GetCC_8u(vec1, vec2, len, 0);
#else
#if defined(MOSIS_DEBUG_ALIGNED_UNALIGNED)
    return Get_CCU8_UA(vec1, vec2, len);
#endif
    int i= 0, s = 0;
    int64 sum = 0;
 
 
#ifdef MOSIS_SIMD
    __m128i    mmResult, mmResult2;
    __m128i    mmA, mmB;
    __m128i    mmAA, mmBB;
    __m128i mmZeroData= _mm_setzero_si128();
    mmResult= _mm_setzero_si128();
 
#ifdef MOSIS_SIMD_INT64_NO
    int64 res64[2];
    int64 sum64= 0;
    for(i= 0; i <= len- 16; i+= 16)
    {
        mmA= _mm_load_si128((__m128i*) (vec1+ i));
        mmB= _mm_load_si128((__m128i*) (vec2+ i));
 
        // 1. »óÀ§ µ¥ÀÌÅÍ °è»ê.
        // 1.1 »óÀ§ 8°³ÀÇ 8bit µ¥ÀÌÅ͸¦ 8°³ÀÇ 16bit µ¥ÀÌÅͷΠº¯È¯ÈÄ.. °öÇÑ´Ù.
        mmAA= _mm_unpackhi_epi8(mmA, mmZeroData);
        mmBB= _mm_unpackhi_epi8(mmB, mmZeroData);
 
        mmResult2= _mm_madd_epi16(mmAA, mmBB);
        mmAA= _mm_unpackhi_epi32(mmResult2, mmZeroData);
        mmBB= _mm_unpacklo_epi32(mmResult2, mmZeroData);
        mmResult= _mm_add_epi64(mmAA, mmResult);
        mmResult= _mm_add_epi64(mmBB, mmResult);
 
 
        mmAA= _mm_unpacklo_epi8(mmA, mmZeroData);
        mmBB= _mm_unpacklo_epi8(mmB, mmZeroData);
 
        mmResult2= _mm_madd_epi16(mmAA, mmBB);
        mmResult= _mm_add_epi32(mmResult2, mmResult);
    }
 
    _mm_storeu_si128((__m128i*)res64, mmResult);
    sum64+= res64[0]+ res64[1];
#endif
    UINT32 results[4];
 
    for(i= 0; i <= len- 16; i+= 16)
    {
 
        mmA= _mm_load_si128((__m128i*) (vec1+ i));
        mmB= _mm_load_si128((__m128i*) (vec2+ i));
 
        // 1. »óÀ§ µ¥ÀÌÅÍ °è»ê.
        // 1.1 »óÀ§ 8°³ÀÇ 8bit µ¥ÀÌÅ͸¦ 8°³ÀÇ 16bit µ¥ÀÌÅͷΠº¯È¯ÈÄ.. °öÇÑ´Ù.
        mmAA= _mm_unpackhi_epi8(mmA, mmZeroData);
        mmBB= _mm_unpackhi_epi8(mmB, mmZeroData);
 
        mmResult2= _mm_madd_epi16(mmAA, mmBB);
        mmResult= _mm_add_epi32(mmResult2, mmResult);
 
 
        mmAA= _mm_unpacklo_epi8(mmA, mmZeroData);
        mmBB= _mm_unpacklo_epi8(mmB, mmZeroData);
 
        mmResult2= _mm_madd_epi16(mmAA, mmBB);
        mmResult= _mm_add_epi32(mmResult2, mmResult);
    }
 
    _mm_storeu_si128((__m128i*)results, mmResult);
    sum+= results[0]+ results[1]+ results[2]+ results[3];
 
#else
    for( i = 0; i <= len - 4; i += 4 )
    {
        int e = vec1[i] * vec2[i];
        int v = vec1[i + 1] * vec2[i + 1];
 
        e += v;
        v = vec1[i + 2] * vec2[i + 2];
        e += v;
        v = vec1[i + 3] * vec2[i + 3];
        e += v;
        sum += e;
    }
#endif
 
    for( ; i < len; i++ )
    {
        s += vec1[i] * vec2[i];
    }
 
    return sum + s;
#endif
}