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 <m...@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 <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 >> 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