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 :).