I recently wrote this little test program to validate that multi-threading was working the way I expected it to.
class Program
{
private delegate void funcs();
static void Main(string[] args)
{
funcs[] functions = new funcs[]
{
new funcs(MultiThreadTest),
new funcs(SingleThreadTest)
};
foreach (funcs function in functions)
{
DateTime startTime = DateTime.Now;
for (int i = 0; i < 10; i++)
{
function();
}
while (ThreadWorker.ThreadCount > 0)
{
Thread.Sleep(1);
}
Console.WriteLine("{0} time taken: {1}",
function.Method.Name, DateTime.Now - startTime);
}
Console.ReadLine();
}
private static void MultiThreadTest()
{
ThreadWorker threadWorker = new ThreadWorker();
ThreadStart threadDelegate =
new ThreadStart(threadWorker.Runner);
Thread newThread = new Thread(threadDelegate);
newThread.Start();
}
private static void SingleThreadTest()
{
ThreadWorker threadWorker = new ThreadWorker();
threadWorker.Runner();
}
}
class ThreadWorker
{
public static int ThreadCount = 0;
public ThreadWorker()
{
ThreadCount++;
}
public void Runner()
{
IEnumerable<string> strings =
Enumerable.Repeat(
@"the not so quick brown fox was
caught by the hen and eaten with eggs", 50);
string text = String.Join(" ",
strings.SelectMany(a => a.Split()).ToArray());
for (int i = 0; i < 1000; i++)
{
// Do some random LINQ stuff to occupy the processor
string[] list = text.Split(' ');
string[] l2 = list.Distinct().ToArray();
l2 = list.OrderBy(a => a).ToArray();
l2 = list.OrderByDescending(a => a).ToArray();
}
ThreadCount--;
}
}
I tested this bit of code by running it four times on each of two machines.
The first was a dual-core and the single-threaded-test took an average of 33.4 seconds and the multi-threaded-test 17.8 seconds. This makes the multi-threaded part 1.9 times faster which is about what you'd expect if you allow two processors to work on the problems in parallel.
The second machine was a quad core with hyper-threading so essentially eight cores. This took an average of 29.3 seconds for the single-threaded-test and 4.6 seconds for the multi-threaded-test. An improvement factor of 6.4, not as close to 8 as I was expecting but not that far off. If anybody knows why the eight cores do not come as close to an eight-times factor as the two cores came to a two-times factor I'd love to hear from you in the comments.
The two processors were:
- Intel Core 2 CPU 6400 @ 2.13 GHz
- Intel Xeon CPU L5410 @ 2.33GHz
Something that I found interesting was that the slower processor ran 1.65 times faster than the fast processor when taking advantage of multi-threading. This has important implications for the software that you write. The single-threaded test ran 1.14 times (14%) faster on the faster processor. However, the multi-threaded code on the slower processor runs 65% faster than the single-threaded code on the faster processor.
If you're looking for a performance boost there may be more performance in multi-threaded code than in a faster processor. In fact, processor speed is probably not what you're looking for. The best combination would be multi-threaded code on multi-core boxes.
I've just run this again on a couple more machines:
ReplyDeleteIntel Core 2 Duo CPU E8500 @ 3.16GHz
11.5 seconds for multi-thread and 21.1 seconds for single-thread with a 1.8 ratio.
Intel Core 2 Quad CPU Q9400 @ 2.66GHz
7.7 seconds for multi and 24.8 for single with a 3.2 ratio.
I'm not exactly sure of the logistics, but I don't believe a HyperThreaded core performs the same as a physical core. I think that the HyperThreaded ones share memory bandwidth with their physical counterpart, thus can't produce the same results.
ReplyDeleteThe real question is where the hell do you get this hardware? I certainly don't have access to Xeons with my personal development :).