Le 25/03/2013 11:50, sebb a écrit :
> On 25 March 2013 10:46, <[email protected]> wrote:
>> Author: luc
>> Date: Mon Mar 25 10:46:42 2013
>> New Revision: 1460604
>>
>> URL: http://svn.apache.org/r1460604
>> Log:
>> Improved speed of FastMath.abs methods, by removing branching.
>>
>> JIRA: MATH-954
>>
>> Modified:
>> commons/proper/math/trunk/src/changes/changes.xml
>>
>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
>>
>> Modified: commons/proper/math/trunk/src/changes/changes.xml
>> URL:
>> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1460604&r1=1460603&r2=1460604&view=diff
>> ==============================================================================
>> --- commons/proper/math/trunk/src/changes/changes.xml (original)
>> +++ commons/proper/math/trunk/src/changes/changes.xml Mon Mar 25 10:46:42
>> 2013
>> @@ -55,10 +55,13 @@ This is a minor release: It combines bug
>> Changes to existing features were made in a backwards-compatible
>> way such as to allow drop-in replacement of the v3.1[.1] JAR file.
>> ">
>> + <action dev="luc" type="update" issue="MATH-954" due-to="Charles
>> Cooper">
>> + Improved speed of FastMath.abs methods for all signatures, by
>> removing branching.
>> + </action>
>> <action dev="luc" type="update" issue="MATH-953" due-to="Charles
>> Cooper">
>> Improved speed of several FastMath methods.
>> </action>
>> - <action dev="luc" type="fix" issue="MATH-934">
>> + <action dev="luc" type="fix" issue="MATH-934">
>> Fixed Complex.reciprocal() for zero argument.
>> </action>
>> <action dev="luc" type="update" issue="MATH-951" due-to="Charles
>> Cooper">
>>
>> Modified:
>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
>> URL:
>> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java?rev=1460604&r1=1460603&r2=1460604&view=diff
>> ==============================================================================
>> ---
>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
>> (original)
>> +++
>> commons/proper/math/trunk/src/main/java/org/apache/commons/math3/util/FastMath.java
>> Mon Mar 25 10:46:42 2013
>> @@ -2987,7 +2987,8 @@ public class FastMath {
>> * @return abs(x)
>> */
>> public static int abs(final int x) {
>> - return (x < 0) ? -x : x;
>> + final int i = x >>> 31;
>> + return (x ^ (~i + 1)) + i;
>
> Are we sure that's faster?
>
> Surely branches aren't significantly slower than arithmetic operations.
The tests I did using Gilles PerfTestUtils show an improvement. Not a
very big one (about 5%), but an improvement.
The reason for that is most probably branch prediction errors at
processor level. Once code has been inlined and compiled to native code,
the prediction of the branch to follow (if or else) drives the speed. As
for an abs() method, I think branch prediction is 50% true, 50% false
(it is not the same for a loop for example, as for example if you
iterate 10 times, it means the condition will be to stay in the loop 9
times and to exit only 1 time).
Luc
>
>> }
>>
>> /**
>> @@ -2996,7 +2997,12 @@ public class FastMath {
>> * @return abs(x)
>> */
>> public static long abs(final long x) {
>> - return (x < 0l) ? -x : x;
>> + final long l = x >>> 63;
>> + // l is one if x negative zero else
>> + // ~l+1 is zero if x is positive, -1 if x is negative
>> + // x^(~l+1) is x is x is positive, ~x if x is negative
>> + // add around
>> + return (x ^ (~l + 1)) + l;
>> }
>>
>> /**
>> @@ -3005,7 +3011,10 @@ public class FastMath {
>> * @return abs(x)
>> */
>> public static float abs(final float x) {
>> - return (x < 0.0f) ? -x : (x == 0.0f) ? 0.0f : x; // -0.0 => +0.0
>> + if ((Float.floatToRawIntBits(x) & Integer.MIN_VALUE) == 0) {
>> + return x;
>> + }
>> + return -x;
>> }
>>
>> /**
>> @@ -3014,7 +3023,10 @@ public class FastMath {
>> * @return abs(x)
>> */
>> public static double abs(double x) {
>> - return (x < 0.0) ? -x : (x == 0.0) ? 0.0 : x; // -0.0 => +0.0
>> + if ((Double.doubleToRawLongBits(x) & Long.MIN_VALUE) == 0) {
>> + return x;
>> + }
>> + return -x;
>> }
>>
>> /**
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]