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