[Libreoffice-commits] core.git: tools/source
Noel Grandin (via logerrit)
logerrit at kemper.freedesktop.org
Sun Dec 20 08:08:54 UTC 2020
tools/source/generic/fract.cxx | 57 ++++++++++-------------------------------
1 file changed, 15 insertions(+), 42 deletions(-)
New commits:
commit 9eb60b50f7dc77851b36e0c2ab4dd3d11a97d099
Author: Noel Grandin <noelgrandin at gmail.com>
AuthorDate: Sat Dec 19 13:24:00 2020 +0200
Commit: Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Sun Dec 20 09:08:09 2020 +0100
use CLZ intrinsic in tools::Fraction
which commonly maps to a fast hardware instruction.
Change-Id: I65d6b4ce03a1813f014aa7ec7fc8f95aa38832d1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108018
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index f5d2c88f4af8..448a70c5ea33 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -35,6 +35,10 @@
#endif
#include <boost/rational.hpp>
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
static boost::rational<sal_Int32> rational_FromDouble(double dVal);
static void rational_ReduceInaccurate(boost::rational<sal_Int32>& rRational, unsigned nSignificantBits);
@@ -420,51 +424,20 @@ static boost::rational<sal_Int32> rational_FromDouble(double dVal)
return boost::rational<sal_Int32>( sal_Int32(dVal), nDen );
}
-// Similar to clz_table that can be googled
-const char nbits_table[32] =
-{
- 32, 1, 23, 2, 29, 24, 14, 3,
- 30, 27, 25, 18, 20, 15, 10, 4,
- 31, 22, 28, 13, 26, 17, 19, 9,
- 21, 12, 16, 8, 11, 7, 6, 5
-};
-
+/**
+ * Find the number of bits required to represent this number, using the CLZ intrinsic
+ */
static int impl_NumberOfBits( sal_uInt32 nNum )
{
- // http://en.wikipedia.org/wiki/De_Bruijn_sequence
- // background paper: Using de Bruijn Sequences to Index a 1 in a
- // Computer Word (1998) Charles E. Leiserson,
- // Harald Prokop, Keith H. Randall
- // (e.g. http://citeseer.ist.psu.edu/leiserson98using.html)
- const sal_uInt32 nDeBruijn = 0x7DCD629;
-
- if ( nNum == 0 )
+ if (nNum == 0)
return 0;
-
- // Get it to form like 0000001111111111b
- nNum |= ( nNum >> 1 );
- nNum |= ( nNum >> 2 );
- nNum |= ( nNum >> 4 );
- nNum |= ( nNum >> 8 );
- nNum |= ( nNum >> 16 );
-
- sal_uInt32 nNumber;
- int nBonus;
-
- nNumber = nNum;
- nBonus = 0;
-
- // De facto shift left of nDeBruijn using multiplication (nNumber
- // is all ones from topmost bit, thus nDeBruijn + (nDeBruijn *
- // nNumber) => nDeBruijn * (nNumber+1) clears all those bits to
- // zero, sets the next bit to one, and thus effectively shift-left
- // nDeBruijn by lg2(nNumber+1). This generates a distinct 5bit
- // sequence in the msb for each distinct position of the last
- // leading 0 bit - that's the property of a de Bruijn number.
- nNumber = nDeBruijn + ( nDeBruijn * nNumber );
-
- // 5-bit window indexes the result
- return ( nbits_table[nNumber >> 27] ) + nBonus;
+#ifdef _MSC_VER
+ unsigned long r = 0;
+ _BitScanReverse(&r, nNum);
+ return r + 1;
+#else
+ return 32 - __builtin_clz(nNum);
+#endif
}
/** Inaccurate cancellation for a fraction.
More information about the Libreoffice-commits
mailing list