Reputation: 193
Why would I be getting such poor performance from the code below?
The following command line uses 16 threads, with a load of 60. On my machine this takes approximately 31 seconds to finish (with some slight variations if you rerun)
testapp.exe 16 60
Using a load of 60, on Microsoft Windows Server 2008 R2 Enterprise SP1, running on 16 Intel Xeon E5-2670 @ 2.6 GHz CPUs I get the following performance:
1 cpu - 305 seconds
2 cpus - 155 seconds
4 cpus - 80 seconds
8 cpus - 45 seconds
10 cpus - 41 seconds
12 cpus - 37 seconds
14 cpus - 34 seconds
16 cpus - 31 seconds
18 cpus - 27 seconds
20 cpus - 24 seconds
22 cpus - 23 seconds
24 cpus - 21 seconds
26 cpus - 20 seconds
28 cpus - 19 seconds
After this it flat-lines ...
I get approximately the same performance using .Net 3.5, 4, 4.5 or 4.5.1.
I understand the drop-off in performance after 22 cpus, as I only have 16 on the box. What I don't understand is the poor performance after 8 cpus. Can anyone explain? Is this normal?
private static void Main(string[] args)
{
int threadCount;
if (args == null || args.Length < 1 || !int.TryParse(args[0], out threadCount))
threadCount = Environment.ProcessorCount;
int load;
if (args == null || args.Length < 2 || !int.TryParse(args[1], out load))
load = 1;
Console.WriteLine("ThreadCount:{0} Load:{1}", threadCount, load);
List<Thread> threads = new List<Thread>();
for (int i = 0; i < threadCount; i++)
{
int i1 = i;
threads.Add(new Thread(() => DoWork(i1, threadCount, load)));
}
Stopwatch timer = Stopwatch.StartNew();
foreach (var thread in threads)
{
thread.Start();
}
foreach (var thread in threads)
{
thread.Join();
}
timer.Stop();
Console.WriteLine("Time:{0} seconds", timer.ElapsedMilliseconds/1000.0);
}
static void DoWork(int seed, int threadCount, int load)
{
double[,] mtx = new double[3,3];
for (int i = 0; i < ((100000 * load)/threadCount); i++)
{
for (int j = 0; j < 100; j++)
{
mtx = new double[3,3];
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 3; l++)
{
mtx[k, l] = Math.Sin(j + (k*3) + l + seed);
}
}
}
}
}
Upvotes: 0
Views: 1012
Reputation: 60
It is not that the threads that causes the performance to go down. But it is the "creation" of the thread itself.
Instead of creating a brand new thread, you need to borrow an already created thread form the OS thread pool. Use ThreadPool
class instead of using new Thread()
Upvotes: 1
Reputation: 424
Please refer to the Intel ARK for the XEON E5-2670
This particular processor has 8 physical cores which are hyper-threaded. This is why you see a performance drop after 8 threads. Calling Environment.ProcessorCount gets 16 logical cores (2 logical cores per physical core because they are hyperthreaded).
A similar question has been answered on SuperUser.
You can try to set the affinity of the threads see if it makes a difference, but the scheduler usually does a good job of allocating resource.
Hope this helps.
Upvotes: 1