git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 87e6ed7)
Frob numeric.c loop so that clang will auto-vectorize it too.
Mon, 7 Sep 2020 16:03:04 +0000 (12:03 -0400)
Mon, 7 Sep 2020 16:03:04 +0000 (12:03 -0400)
Experimentation shows that clang will auto-vectorize the critical
multiplication loop if the termination condition is written "i2 < limit"
rather than "i2 <= limit". This seems unbelievably stupid, but I've
reproduced it on both clang 9.0.1 (RHEL8) and 11.0.3 (macOS Catalina).
gcc doesn't care, so tweak the code to do it that way.

Discussion: https://postgr.es/m/CAJ3gD9evtA_vBo+WMYMyT-u=keHX7-r8p2w7OSRfXf42LTwCZQ@mail.gmail.com


diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index d2a42b811daca8d707827e0764441fb26c7ea1b0..dfd455fc748816ac588828c7f24cff8030727641 100644 (file)
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -8191,7 +8191,6 @@ mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
int res_weight;
int maxdigits;
int *dig;
- int *dig_i1_2;
int carry;
int maxdig;
int newdig;
@@ -8327,7 +8326,7 @@ mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
* Add the appropriate multiple of var2 into the accumulator.
*
* As above, digits of var2 can be ignored if they don't contribute,
- * so we only include digits for which i1+i2+2 <= res_ndigits - 1.
+ * so we only include digits for which i1+i2+2 < res_ndigits.
*
* This inner loop is the performance bottleneck for multiplication,
* so we want to keep it simple enough so that it can be
@@ -8336,10 +8335,13 @@ mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
* Since we aren't propagating carries in this loop, the order does
* not matter.
*/
- i = Min(var2ndigits - 1, res_ndigits - i1 - 3);
- dig_i1_2 = &dig[i1 + 2];
- for (i2 = 0; i2 <= i; i2++)
- dig_i1_2[i2] += var1digit * var2digits[i2];
+ {
+ int i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
+ int *dig_i1_2 = &dig[i1 + 2];
+
+ for (i2 = 0; i2 < i2limit; i2++)
+ dig_i1_2[i2] += var1digit * var2digits[i2];
+ }
}
/*
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /