diff --git a/CHANGELOG.md b/CHANGELOG.md index 27dcb50..c85bcf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.8.1 (unreleased) - Added support for Postgres 18 +- Improved performance of `binary_quantize` function ## 0.8.0 (2024-10-30) diff --git a/src/halfvec.c b/src/halfvec.c index aad320b..e255b53 100644 --- a/src/halfvec.c +++ b/src/halfvec.c @@ -898,8 +898,21 @@ halfvec_binary_quantize(PG_FUNCTION_ARGS) half *ax = a->x; VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); + int i = 0; + int count = (a->dim / 8) * 8; - for (int i = 0; i < a->dim; i++) + /* Auto-vectorized */ + for (; i < count; i += 8) + { + unsigned char result_byte = 0; + + for (int j = 0; j < 8; j++) + result_byte |= (HalfToFloat4(ax[i + j]) > 0) << (7 - j); + + rx[i / 8] = result_byte; + } + + for (; i < a->dim; i++) rx[i / 8] |= (HalfToFloat4(ax[i]) > 0) << (7 - (i % 8)); PG_RETURN_VARBIT_P(result); diff --git a/src/vector.c b/src/vector.c index 4c1f695..0630cf8 100644 --- a/src/vector.c +++ b/src/vector.c @@ -946,17 +946,20 @@ binary_quantize(PG_FUNCTION_ARGS) float *ax = a->x; VarBit *result = InitBitVector(a->dim); unsigned char *rx = VARBITS(result); - int i; + int i = 0; int count = (a->dim / 8) * 8; - unsigned char result_byte; - for (i = 0; i < count; i += 8) + /* Auto-vectorized */ + for (; i < count; i += 8) { - result_byte = 0; + unsigned char result_byte = 0; + for (int j = 0; j < 8; j++) result_byte |= (ax[i + j] > 0) << (7 - j); + rx[i / 8] = result_byte; } + for (; i < a->dim; i++) rx[i / 8] |= (ax[i] > 0) << (7 - (i % 8));