[Mono-dev] Multi-threading problem in mono

Zoltan Varga vargaz at gmail.com
Fri May 7 22:01:27 EDT 2010


Hi,

  I don't think it is fixed in any mono version, it might worked for him by
accident. This can be
considered a bug in our garbage collector, hopefully our new sgen gc which
is in development
won't have this problem, since each thread will allocate from a separate
memory region.

                            Zoltan

On Sat, May 8, 2010 at 3:37 AM, Maximino Aldana <max at fis.unam.mx> wrote:

>
> 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> 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/d49738d9/attachment.html 


More information about the Mono-devel-list mailing list