Hi Zoltan,

Thanks a lot!! Yes, that trick solved the problem. Robert Jordan also pointed out that this problem was apparently fixed in mono2.6, so I'm installing it now (currently I have mono2.4 because it is the one that comes with my Ubuntu distribution).

Thanks again.

MAX


On 05/07/2010 07:24 PM, Zoltan Varga wrote:
Hi,

You might be running into cpu cache effects, i.e. the 3 Random objects get allocated to the same cpu cache line or something, so you have 3 cpu cores modifying the same cache line.
If I change the creation of the random objects to:

Random[] rands = new Random [1000];
for (int i = 0; i < 10; ++i) {
rands [i] = new Random ();
}
                        this.rnd = rands [5];

I get perfect scalability, i.e. a 3x speedup with 3 threads on a quad core machine.

                     Zoltan

On Sat, May 8, 2010 at 1:04 AM, Maximino Aldana <m...@fis.unam.mx <mailto:m...@fis.unam.mx>> wrote:


    Dear mono developers.

    I'm writing a C# multi-threading program in which the threads do not
    share any information, so no thread synchronization is needed. Each
    thread has its own internal variables, none of which is static,
    and all
    the threads perform exactly the same task but with different values of
    the parameters. I'm running this program in a multi-core processor
    computer (Intel Quad-core), and therefore I expect the program to run
    faster when the job is divided among several threads than when the
    entire job is carried out only by a single thread.

    However, it happens exactly the opposite. Namely, when the job is
    performed by several threads the execution time is considerably longer
    than when only one thread performs the entire job.

    To be more specific, look at the example listed below (at the end of
    this e-mail), in which I have encapsulated the thread in a MyThread
    class. The MyThread class performs a very simple task: it just
    generates
    a bunch of random numbers and computes their square root. This is a
    simplified version of the thread I was working with in my original
    project. However, even such a simple object exhibits the pathology I
    would like you to ask how to solve. It is important to stress the fact
    that each MyThread object creates its own internal variables,
    including
    the random number generator, and (apparently) no sharing of the
    instance
    variables occurs at any time.

    I have run the program listed below in two cases:

    Case 1: The three threads run sequentially. This is done by starting a
    thread and calling on its Join() method before the next thread starts
    (in the program listed below, the three lines calling the Join()
    method
    are uncommented). In this case, the SystemMonitor shows only one core
    working at any time, and the execution of the three threads running
    sequentially takes 25.894 seconds.

    Case 2: The three threads run in parallel (no calling on the Join()
    method occurs here because the three lines that call the Join() method
    are commented). In this case the SystemMonitor shows several cores
    working simultaneously, as expected. However, what is not expected is
    that the execution of the three threads running in parallel takes
    42.307
    seconds!!!

    In summary, the three threads running in parallel and with many cores
    working simultaneously, run about 1.6 times SLOWER than the three
    threads running sequentially with only one core working at a time. How
    can this be possible?

    It is important to mention that I run exactly the same program and in
    the same machine, but in Windows 7 using the C# Express .NET
    environment
    2010, and the performance was consistent with what I expected from the
    very beginning. Namely, the three threads running in parallel did the
    job in one third of the time than the three threads running
    sequentially. The same consistency happened when I implemented the
    program in Java 6, both in Windows 7 and in Ubuntu Linux 10.04.

    So, the problem, as I have encountered it, occurs only with the
    implementation of this program in mono. (I did the mono experiments in
    Linux. I have not tried running mono in Windows).

    I suspect the problem resides in the implementation of the Random
    class
    (probably some static variables in there??), but I'm not sure and my
    programming skills do not allow me to dig that far.

    I thank you in advance for your help. Below is the code.

    Maximino Aldana.


    *********************************
    using System;
    using System.Threading;

    namespace Pruebas
    {


        public class MyThread
        {
            Thread t;
            Random rnd;
            int i_max;
            int t_num;

            public MyThread (int tn, int im)
            {
                this.rnd = new Random();
                this.t = new Thread(new ThreadStart(MyMethod));

                this.t_num = tn;
                this.i_max = im;
            }

            private void MyMethod(){
                double x, y;
                Console.WriteLine("Method in thread {0} started",t_num);
                for(int n = 0; n < 10000; ++n){
                    for(int i = 0; i < i_max; ++i){
                        x = rnd.NextDouble();
                        y = Math.Sqrt(x);
                    }
                }
                Console.WriteLine("Method in thread {0} ended",t_num);
            }

            public void StartMyThread(){
                t.Start();
            }
            public void JoinMyThread(){
                t.Join();
            }
        }
    }

    // ******* Now the entry point **************

    using System;

    namespace Pruebas
    {
        class MainClass
        {
            public static void Main(string[] args)
            {
                MyThread t1 = new MyThread(1, 50000);
                MyThread t2 = new MyThread(2, 50000);
                MyThread t3 = new MyThread(3, 50000);

                t1.StartMyThread();
                // t1.JoinMyThread();

                t2.StartMyThread();
                // t2.JoinMyThread();

                t3.StartMyThread();
                // t3.JoinMyThread();

                /* Comment or uncomment the calls to the JoinMyThread()
                 * method to make the threads run in parallel or
    sequentially.
                */

            }
        }
    }
    *******************************


    _______________________________________________
    Mono-devel-list mailing list
    Mono-devel-list@lists.ximian.com
    <mailto:Mono-devel-list@lists.ximian.com>
    http://lists.ximian.com/mailman/listinfo/mono-devel-list



_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to