[Mono-dev] Multi-threading problem in mono

Zoltan Varga vargaz at gmail.com
Fri May 7 20:24:18 EDT 2010


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 <max at 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 at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20100508/f7c84140/attachment.html 


More information about the Mono-devel-list mailing list