Le 25/03/2013 12:56, sebb a écrit :
> On 25 March 2013 11:44, Luc Maisonobe <[email protected]> wrote:
>> 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).
>
> What about
>
> if (x >= 0) return x;
> return -x;
>
> Would that be any faster?
No, it is still branching.
> It's simpler to read.
Sure.
Luc
>
>> 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]
>>
>
> ---------------------------------------------------------------------
> 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]