Skip to content

Commit 8709e3a

Browse files
committed
improved HNSW graph construction performance
1 parent 0492fdf commit 8709e3a

4 files changed

Lines changed: 182 additions & 44 deletions

File tree

cmake/GetHNSW.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
16-
set ( HNSW_GITHUB "https://github.com/manticoresoftware/hnswlib/archive/3c50a66.zip" )
16+
set ( HNSW_GITHUB "https://github.com/manticoresoftware/hnswlib/archive/091f3dd.zip" )
1717
set ( HNSW_BUNDLEZIP "${LIBS_BUNDLE}/hnswlib-0.7.0.tar.gz" )
1818

1919
cmake_minimum_required ( VERSION 3.17 FATAL_ERROR )

knn/knn.cpp

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,48 @@ class L2BinarySIMD16ResidualsDistFn_c : public DistFnDispatch_c<&L2BinaryFloatDi
310310
};
311311
#endif
312312

313+
// build-mode DistFn classes
314+
using IPBinaryGenericBuildDistFn_c = DistFnDispatch_c<&IPBinaryFloatDistanceGenericBuild>;
315+
using L2BinaryGenericBuildDistFn_c = DistFnDispatch_c<&L2BinaryFloatDistanceGenericBuild>;
316+
317+
#if !defined(USE_SIMDE)
318+
class IPBinarySIMD16BuildDistFn_c : public DistFnDispatch_c<&IPBinaryFloatDistanceSIMD16Build>
319+
{
320+
public:
321+
static void Eval2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
322+
{
323+
IPBinaryFloatDistanceSIMD16Batch2Build ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
324+
}
325+
};
326+
327+
class IPBinarySIMD16ResidualsBuildDistFn_c : public DistFnDispatch_c<&IPBinaryFloatDistanceSIMD16ResidualsBuild>
328+
{
329+
public:
330+
static void Eval2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
331+
{
332+
IPBinaryFloatDistanceSIMD16ResidualsBatch2Build ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
333+
}
334+
};
335+
336+
class L2BinarySIMD16BuildDistFn_c : public DistFnDispatch_c<&L2BinaryFloatDistanceSIMD16Build>
337+
{
338+
public:
339+
static void Eval2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
340+
{
341+
L2BinaryFloatDistanceSIMD16Batch2Build ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
342+
}
343+
};
344+
345+
class L2BinarySIMD16ResidualsBuildDistFn_c : public DistFnDispatch_c<&L2BinaryFloatDistanceSIMD16ResidualsBuild>
346+
{
347+
public:
348+
static void Eval2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
349+
{
350+
L2BinaryFloatDistanceSIMD16ResidualsBatch2Build ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
351+
}
352+
};
353+
#endif
354+
313355
template <typename DistFn = void>
314356
static void RunSearchPath ( const hnswlib::HierarchicalNSW<float> & tAlg, std::vector<DocDist_t> & dResults, const void * pData, int64_t iResults, HNSWFilterWrapper_c * pFilter, size_t * pSearchEf, int iSearchPath )
315357
{
@@ -558,18 +600,49 @@ class HNSWIndexBuilder_c : public HNSWIndexBuilder_i, public HNSWDist_c
558600
const QuantizationSettings_t & GetQuantizationSettings() const override { return m_pQuantizer->GetSettings(); }
559601

560602
private:
561-
AttrWithSettings_t m_tAttr;
562-
std::unique_ptr<ScalarQuantizer_i> m_pQuantizer;
563-
std::unique_ptr<hnswlib::HierarchicalNSW<float>> m_pAlg;
603+
using AddPoint_fn = void (*) ( hnswlib::HierarchicalNSW<float> &, const void *, uint32_t );
604+
605+
template <typename DistFn>
606+
static void AddPointTyped ( hnswlib::HierarchicalNSW<float> & tAlg, const void * pVec, uint32_t uRowID ) { tAlg.template addPoint<DistFn, false> ( pVec, (size_t)uRowID, -1 ); }
607+
static void AddPointFallback ( hnswlib::HierarchicalNSW<float> & tAlg, const void * pVec, uint32_t uRowID ) { tAlg.addPoint ( pVec, (size_t)uRowID ); }
608+
AddPoint_fn SelectAddPointFn() const;
609+
610+
AttrWithSettings_t m_tAttr;
611+
std::unique_ptr<ScalarQuantizer_i> m_pQuantizer;
612+
std::unique_ptr<hnswlib::HierarchicalNSW<float>> m_pAlg;
613+
AddPoint_fn m_fnAddPoint = AddPointFallback;
564614
};
565615

566616

617+
HNSWIndexBuilder_c::AddPoint_fn HNSWIndexBuilder_c::SelectAddPointFn() const
618+
{
619+
switch ( m_pSpace->GetDistFuncId() )
620+
{
621+
case DistFuncId_e::IP_FLOAT32: return AddPointTyped<IPFloatDistFn_c>;
622+
case DistFuncId_e::L2_FLOAT32: return AddPointTyped<L2FloatDistFn_c>;
623+
case DistFuncId_e::IP_BINARY_GENERIC: return AddPointTyped<IPBinaryGenericBuildDistFn_c>;
624+
case DistFuncId_e::L2_BINARY_GENERIC: return AddPointTyped<L2BinaryGenericBuildDistFn_c>;
625+
626+
#if !defined(USE_SIMDE)
627+
case DistFuncId_e::IP_BINARY_SIMD16: return AddPointTyped<IPBinarySIMD16BuildDistFn_c>;
628+
case DistFuncId_e::IP_BINARY_SIMD16_RESIDUALS: return AddPointTyped<IPBinarySIMD16ResidualsBuildDistFn_c>;
629+
case DistFuncId_e::L2_BINARY_SIMD16: return AddPointTyped<L2BinarySIMD16BuildDistFn_c>;
630+
case DistFuncId_e::L2_BINARY_SIMD16_RESIDUALS: return AddPointTyped<L2BinarySIMD16ResidualsBuildDistFn_c>;
631+
#endif
632+
633+
default:
634+
return AddPointFallback;
635+
}
636+
}
637+
638+
567639
HNSWIndexBuilder_c::HNSWIndexBuilder_c ( const AttrWithSettings_t & tAttr, int64_t iNumElements, ScalarQuantizer_i * pQuantizer )
568640
: HNSWDist_c ( tAttr.m_iDims, tAttr.m_eHNSWSimilarity, tAttr.m_eQuantization, true )
569641
, m_tAttr ( tAttr )
570642
, m_pQuantizer ( pQuantizer )
571643
{
572644
m_pAlg = std::make_unique<hnswlib::HierarchicalNSW<float>>( m_pSpace.get(), iNumElements, m_tAttr.m_iHNSWM, m_tAttr.m_iHNSWEFConstruction );
645+
m_fnAddPoint = SelectAddPointFn();
573646
}
574647

575648

@@ -615,13 +688,16 @@ bool HNSWIndexBuilder_c::AddDoc ( uint32_t uRowID, const util::Span_T<float> & d
615688
dToAdd = tBuildCtx.m_dNormalized;
616689
}
617690

691+
const void * pVec = nullptr;
618692
if ( m_pQuantizer )
619693
{
620694
m_pQuantizer->Encode ( uRowID, dToAdd, tBuildCtx.m_dQuantized, tBuildCtx.m_dQuantizedForQuery );
621-
m_pAlg->addPoint ( (void*)tBuildCtx.m_dQuantized.data(), (size_t)uRowID );
695+
pVec = (void*)tBuildCtx.m_dQuantized.data();
622696
}
623697
else
624-
m_pAlg->addPoint ( (void*)dToAdd.data(), (size_t)uRowID );
698+
pVec = (void*)dToAdd.data();
699+
700+
m_fnAddPoint ( *m_pAlg, pVec, uRowID );
625701

626702
return true;
627703
}

knn/space.cpp

Lines changed: 90 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ static FORCE_INLINE float L2BinaryFloatDistanceFromHammingDist ( const Binary4Bi
11381138

11391139

11401140
template<bool BUILD, int64_t (*DOTPRODUCT_FN)( const uint8_t * pVec4Bit, const uint8_t * pVec1Bit, int iBytes )>
1141-
static float IPBinaryFloatDistance ( const void * __restrict pVect1, const void * __restrict pVect2, size_t uRowID1, size_t uRowID2, const void * __restrict pParam )
1141+
FORCE_INLINE static float IPBinaryFloatDistance ( const void * __restrict pVect1, const void * __restrict pVect2, size_t uRowID1, size_t uRowID2, const void * __restrict pParam )
11421142
{
11431143
const auto & tBinaryParam = *(const DistFuncParamBinary_t*)pParam;
11441144

@@ -1173,7 +1173,7 @@ static float IPBinaryFloatDistance ( const void * __restrict pVect1, const void
11731173
// in org.elasticsearch.index.codec.vectors.es816.ES816BinaryFlatVectorsScorer
11741174
// Permalink: https://github.com/elastic/elasticsearch/blob/1dd41ec2b683a7b7c9c16af404b842cf85cbd5bc/server/src/main/java/org/elasticsearch/index/codec/vectors/es816/ES816BinaryFlatVectorsScorer.java
11751175
template<bool BUILD, int64_t (*DOTPRODUCT_FN)( const uint8_t * pVec4Bit, const uint8_t * pVec1Bit, int iBytes )>
1176-
static float L2BinaryFloatDistance ( const void * __restrict pVect1, const void * __restrict pVect2, size_t uRowID1, size_t uRowID2, const void * __restrict pParam )
1176+
FORCE_INLINE static float L2BinaryFloatDistance ( const void * __restrict pVect1, const void * __restrict pVect2, size_t uRowID1, size_t uRowID2, const void * __restrict pParam )
11771177
{
11781178
const auto & tBinaryParam = *(const DistFuncParamBinary_t*)pParam;
11791179

@@ -1211,32 +1211,60 @@ float IPBinaryFloatDistanceGeneric ( const void * pVect1, const void * pVect2, s
12111211
return IPBinaryFloatDistance<false,BinaryDotProduct> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12121212
}
12131213

1214+
float IPBinaryFloatDistanceGenericBuild ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1215+
{
1216+
return IPBinaryFloatDistance<true,BinaryDotProduct> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1217+
}
1218+
12141219
float L2BinaryFloatDistanceGeneric ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
12151220
{
12161221
return L2BinaryFloatDistance<false,BinaryDotProduct> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12171222
}
12181223

1224+
float L2BinaryFloatDistanceGenericBuild ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1225+
{
1226+
return L2BinaryFloatDistance<true,BinaryDotProduct> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1227+
}
1228+
12191229
#if !defined(USE_SIMDE)
12201230

12211231
float IPBinaryFloatDistanceSIMD16 ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
12221232
{
12231233
return IPBinaryFloatDistance<false,BinaryDotProduct16<false>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12241234
}
12251235

1236+
float IPBinaryFloatDistanceSIMD16Build ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1237+
{
1238+
return IPBinaryFloatDistance<true,BinaryDotProduct16<false>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1239+
}
1240+
12261241
float IPBinaryFloatDistanceSIMD16Residuals ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
12271242
{
12281243
return IPBinaryFloatDistance<false,BinaryDotProduct16<true>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12291244
}
12301245

1231-
template <bool RESIDUALS>
1232-
static void IPBinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1246+
float IPBinaryFloatDistanceSIMD16ResidualsBuild ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1247+
{
1248+
return IPBinaryFloatDistance<true,BinaryDotProduct16<true>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1249+
}
1250+
1251+
template <bool BUILD, bool RESIDUALS>
1252+
FORCE_INLINE static void IPBinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
12331253
{
12341254
const auto & tBinaryParam = *(const DistFuncParamBinary_t*)pParam;
12351255

12361256
auto pV1 = (const uint8_t *)pVect1;
12371257
auto pVA = (const uint8_t *)pVect2A;
12381258
auto pVB = (const uint8_t *)pVect2B;
12391259

1260+
// Build mode: source is 1-bit raw data; fetch its 4-bit representation from the pool
1261+
// using the source row id. Amortized over both candidates by doing this once.
1262+
if constexpr ( BUILD )
1263+
{
1264+
if ( uRowID1!=(size_t)-1 )
1265+
pV1 = tBinaryParam.m_fnFetcher(uRowID1);
1266+
}
1267+
12401268
assert ( uRowID2A!=(size_t)-1 );
12411269
assert ( uRowID2B!=(size_t)-1 );
12421270

@@ -1258,33 +1286,59 @@ static void IPBinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVec
12581286

12591287
void IPBinaryFloatDistanceSIMD16Batch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
12601288
{
1261-
IPBinaryFloatDistanceBatch2<false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1289+
IPBinaryFloatDistanceBatch2<false,false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1290+
}
1291+
1292+
void IPBinaryFloatDistanceSIMD16Batch2Build ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1293+
{
1294+
IPBinaryFloatDistanceBatch2<true,false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
12621295
}
12631296

12641297
void IPBinaryFloatDistanceSIMD16ResidualsBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
12651298
{
1266-
IPBinaryFloatDistanceBatch2<true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1299+
IPBinaryFloatDistanceBatch2<false,true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1300+
}
1301+
1302+
void IPBinaryFloatDistanceSIMD16ResidualsBatch2Build ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1303+
{
1304+
IPBinaryFloatDistanceBatch2<true,true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
12671305
}
12681306

12691307
float L2BinaryFloatDistanceSIMD16 ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
12701308
{
12711309
return L2BinaryFloatDistance<false,BinaryDotProduct16<false>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12721310
}
12731311

1312+
float L2BinaryFloatDistanceSIMD16Build ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1313+
{
1314+
return L2BinaryFloatDistance<true,BinaryDotProduct16<false>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1315+
}
1316+
12741317
float L2BinaryFloatDistanceSIMD16Residuals ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
12751318
{
12761319
return L2BinaryFloatDistance<false,BinaryDotProduct16<true>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
12771320
}
12781321

1279-
template <bool RESIDUALS>
1280-
static void L2BinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1322+
float L2BinaryFloatDistanceSIMD16ResidualsBuild ( const void * pVect1, const void * pVect2, size_t uRowID1, size_t uRowID2, const void * pParam )
1323+
{
1324+
return L2BinaryFloatDistance<true,BinaryDotProduct16<true>> ( pVect1, pVect2, uRowID1, uRowID2, pParam );
1325+
}
1326+
1327+
template <bool BUILD, bool RESIDUALS>
1328+
static FORCE_INLINE void L2BinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
12811329
{
12821330
const auto & tBinaryParam = *(const DistFuncParamBinary_t*)pParam;
12831331

12841332
auto pV1 = (const uint8_t *)pVect1;
12851333
auto pVA = (const uint8_t *)pVect2A;
12861334
auto pVB = (const uint8_t *)pVect2B;
12871335

1336+
if constexpr ( BUILD )
1337+
{
1338+
if ( uRowID1!=(size_t)-1 )
1339+
pV1 = tBinaryParam.m_fnFetcher(uRowID1);
1340+
}
1341+
12881342
assert ( uRowID2A!=(size_t)-1 );
12891343
assert ( uRowID2B!=(size_t)-1 );
12901344

@@ -1306,12 +1360,22 @@ static void L2BinaryFloatDistanceBatch2 ( const void * pVect1, const void * pVec
13061360

13071361
void L2BinaryFloatDistanceSIMD16Batch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
13081362
{
1309-
L2BinaryFloatDistanceBatch2<false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1363+
L2BinaryFloatDistanceBatch2<false,false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1364+
}
1365+
1366+
void L2BinaryFloatDistanceSIMD16Batch2Build ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1367+
{
1368+
L2BinaryFloatDistanceBatch2<true,false> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
13101369
}
13111370

13121371
void L2BinaryFloatDistanceSIMD16ResidualsBatch2 ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
13131372
{
1314-
L2BinaryFloatDistanceBatch2<true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1373+
L2BinaryFloatDistanceBatch2<false,true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
1374+
}
1375+
1376+
void L2BinaryFloatDistanceSIMD16ResidualsBatch2Build ( const void * pVect1, const void * pVect2A, const void * pVect2B, size_t uRowID1, size_t uRowID2A, size_t uRowID2B, const void * pParam, float & fDistA, float & fDistB )
1377+
{
1378+
L2BinaryFloatDistanceBatch2<true,true> ( pVect1, pVect2A, pVect2B, uRowID1, uRowID2A, uRowID2B, pParam, fDistA, fDistB );
13151379
}
13161380

13171381
#endif // !USE_SIMDE
@@ -1341,13 +1405,10 @@ IPSpaceBinaryFloat_c::IPSpaceBinaryFloat_c ( size_t uDim, bool bBuild )
13411405
, m_tDistFuncParam ( uDim )
13421406
{
13431407
#if defined(USE_SIMDE)
1344-
if ( bBuild )
1345-
m_fnDist = IPBinaryFloatDistance<true,BinaryDotProduct>;
1346-
else
1347-
{
1348-
m_fnDist = IPBinaryFloatDistance<false,BinaryDotProduct>;
1349-
m_eDistFuncId = DistFuncId_e::IP_BINARY_GENERIC;
1350-
}
1408+
m_fnDist = bBuild
1409+
? IPBinaryFloatDistance<true,BinaryDotProduct>
1410+
: IPBinaryFloatDistance<false,BinaryDotProduct>;
1411+
m_eDistFuncId = DistFuncId_e::IP_BINARY_GENERIC;
13511412
#else
13521413
int iBytes = ( uDim+7 ) >> 3;
13531414
bool bUseSSE = iBytes>=16;
@@ -1367,13 +1428,10 @@ IPSpaceBinaryFloat_c::IPSpaceBinaryFloat_c ( size_t uDim, bool bBuild )
13671428
case 7: m_fnDist = IPBinaryFloatDistance<true, BinaryDotProduct16<true>>; break;
13681429
}
13691430

1370-
if ( !bBuild )
1371-
{
1372-
if ( bUseSSE )
1373-
m_eDistFuncId = bNeedResiduals ? DistFuncId_e::IP_BINARY_SIMD16_RESIDUALS : DistFuncId_e::IP_BINARY_SIMD16;
1374-
else
1375-
m_eDistFuncId = DistFuncId_e::IP_BINARY_GENERIC;
1376-
}
1431+
if ( bUseSSE )
1432+
m_eDistFuncId = bNeedResiduals ? DistFuncId_e::IP_BINARY_SIMD16_RESIDUALS : DistFuncId_e::IP_BINARY_SIMD16;
1433+
else
1434+
m_eDistFuncId = DistFuncId_e::IP_BINARY_GENERIC;
13771435
#endif
13781436
}
13791437

@@ -1391,13 +1449,10 @@ L2SpaceBinaryFloat_c::L2SpaceBinaryFloat_c ( size_t uDim, bool bBuild )
13911449
, m_tDistFuncParam ( uDim )
13921450
{
13931451
#if defined(USE_SIMDE)
1394-
if ( bBuild )
1395-
m_fnDist = L2BinaryFloatDistance<true,BinaryDotProduct>;
1396-
else
1397-
{
1398-
m_fnDist = L2BinaryFloatDistance<false,BinaryDotProduct>;
1399-
m_eDistFuncId = DistFuncId_e::L2_BINARY_GENERIC;
1400-
}
1452+
m_fnDist = bBuild
1453+
? L2BinaryFloatDistance<true,BinaryDotProduct>
1454+
: L2BinaryFloatDistance<false,BinaryDotProduct>;
1455+
m_eDistFuncId = DistFuncId_e::L2_BINARY_GENERIC;
14011456
#else
14021457
int iBytes = ( uDim+7 ) >> 3;
14031458
bool bUseSSE = iBytes>=16;
@@ -1417,13 +1472,10 @@ L2SpaceBinaryFloat_c::L2SpaceBinaryFloat_c ( size_t uDim, bool bBuild )
14171472
case 7: m_fnDist = L2BinaryFloatDistance<true, BinaryDotProduct16<true>>; break;
14181473
}
14191474

1420-
if ( !bBuild )
1421-
{
1422-
if ( bUseSSE )
1423-
m_eDistFuncId = bNeedResiduals ? DistFuncId_e::L2_BINARY_SIMD16_RESIDUALS : DistFuncId_e::L2_BINARY_SIMD16;
1424-
else
1425-
m_eDistFuncId = DistFuncId_e::L2_BINARY_GENERIC;
1426-
}
1475+
if ( bUseSSE )
1476+
m_eDistFuncId = bNeedResiduals ? DistFuncId_e::L2_BINARY_SIMD16_RESIDUALS : DistFuncId_e::L2_BINARY_SIMD16;
1477+
else
1478+
m_eDistFuncId = DistFuncId_e::L2_BINARY_GENERIC;
14271479
#endif
14281480
}
14291481

0 commit comments

Comments
 (0)