Why x64 app runs slower than x86 app ?

O

Oleg Subachev

I have played with Parallel Extensions and noticed to my surprise that
executable compiled for x64 runs slower than compiled for x86:

private static double HeavyMath( int I )
{
double D1 = Math.Sqrt( I ) * Math.Pow( I, Math.PI ) * Math.Pow( I, 1 /
Math.E );
double D2 = Math.Sqrt( I ) / Math.Pow( I, Math.PI ) / Math.Pow( I, 1 /
Math.E );
return D1 / D2 + D2 / D1;
}

private static double Sequential( int N )
{
double R = 0;
for ( int I = 1; I <= N; I++ )
{
double D = HeavyMath( I );
R += D;
}
return R;
}

private static object lockThis = new object();

private static double Parallel1( int N )
{
double R = 0;
Parallel.For( 1, N + 1,
I =>
{
double D = HeavyMath( I );
lock ( lockThis )
{
R += D;
}
}
);
return R;
}

private static void CallMethod( Func<int, double> M )
{
Stopwatch SW;
double D;
const int N = 20000000;

SW = Stopwatch.StartNew();
D = M( N );
SW.Stop();
Console.WriteLine( "{0}: {1:F0}", M.Method.Name, D );
Console.WriteLine( "{0}: {1} ms", M.Method.Name,
SW.ElapsedMilliseconds );
}

static void Main( string[] args )
{
CallMethod( Sequential );
CallMethod( Parallel1 );
}

Sequential method takes ~11,2 sec if compiled for x64, but only ~9,8 sec if
compiled for x86.
Parallel1 method takes ~7,1 sec if compiled for x64, but only ~6,7 sec if
compiled for x86.

Environment is VS2008, Vista Ultimate 64-bit, Core 2 Duo 2.40 GHz.

Are such times result from use of double arithmetic ?
Or what else ?

Oleg Subachev
 
M

Marc Gravell

Well, one thing that occurs is that you can never trust the first run
for performance - "fusion", JIT - other things all contribute heavily
the first time through an execution path, and it could be that the
64-bit fusion/JIT is slower (juts a guess).

I would try running it twice in succession (in the same process), and
only look at the second set of numbers (which should be smaller for both
64 and 32)... does this make it any better?

Marc
 
O

Oleg Subachev

I would try running it twice in succession (in the same process), and only
look at the second set of numbers (which should be smaller for both 64 and
32)... does this make it any better?

Here are the results of the following Main method:

static void Main( string[] args )
{
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
}

x64:
Sequential: 11264 ms 11244 ms 11249 ms 11249 ms
Parallel1: 6985 ms 6851 ms 6861 ms 6862 ms

x86:
Sequential: 9870 ms 9861 ms 9865 ms 9859 ms
Parallel1: 6700 ms 6579 ms 6581 ms 6587 ms


Oleg Subachev
 
W

Willy Denoyette [MVP]

Oleg Subachev said:
I would try running it twice in succession (in the same process), and
only look at the second set of numbers (which should be smaller for both
64 and 32)... does this make it any better?

Here are the results of the following Main method:

static void Main( string[] args )
{
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
CallMethod( Sequential );
CallMethod( Parallel1 );
}

x64:
Sequential: 11264 ms 11244 ms 11249 ms 11249 ms
Parallel1: 6985 ms 6851 ms 6861 ms 6862 ms

x86:
Sequential: 9870 ms 9861 ms 9865 ms 9859 ms
Parallel1: 6700 ms 6579 ms 6581 ms 6587 ms


Oleg Subachev



First of all you should never assume that X64 code will run faster than X86
code, 64 bit comes at a price, but, here it is slower.
The reason for this is that the CLR is not optimized to take advantage of
the features available in the newest AMD and Intel multicore processors,
notably the Math.Pow function does not take advantage of the newest floating
point arithmetic unit available, the x64 clr uses xmm + x87 FPU for
Math.Pow, while x86 clr uses the x87 FPU. It looks like the X86 Math.Pow
function is better optimized than the 64-bit version, no big surprise here,
MS doesn't care that much about 64-bit .NET.


Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top