[Mono-dev] Multi-threading problem in mono

Maximino Aldana max at fis.unam.mx
Fri May 7 21:37:33 EDT 2010


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 <max at fis.unam.mx 
> <mailto: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
>     <mailto: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/20100507/aac8a0ae/attachment-0001.html 


More information about the Mono-devel-list mailing list