1

There is such an array, I know what is needed through Thread, but I don’t understand how to do it. Do you need to split the array into parts, or can you do something right away?

Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();
                int[] a = new int[10000];
                Random rand = new Random();
    
                for (int i = 0; i < a.Length; i++)
                {
                    a[i] = rand.Next(-100, 100);
                }
                foreach (var p in a)
                    Console.WriteLine(p);
                TimeSpan ts = stopWatch.Elapsed;
                stopWatch.Stop();
                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds / 10);
                Console.WriteLine("RunTime " + elapsedTime);
1
  • 1
    As you've learned from the answers, this is something you generally don't want to do, though it's certainly a good pedagogical exercise. Commented Mar 23, 2021 at 0:21

2 Answers 2

3

Another approach, compared to John Wu's, is to use a custom partitioner. I think that it is a little more readable.

using System.Collections.Concurrent;
using System.Threading.Tasks;

int[] a = new int[10000];
int batchSize = 1000;
Random rand = new Random();

Parallel.ForEach(Partitioner.Create(0, a.Length, batchSize), range =>
{
     for (int i = range.Item1; i < range.Item2; i++)
     {
         a[i] = rand.Next(-100, 100);
     }
});
Sign up to request clarification or add additional context in comments.

6 Comments

The oddity is that when multithreaded array filling takes more time than when filling in 1 thread. Even if you fill in 1,000,000,000
@ebw1910 this is because of memory caching in the processor. Each time you switch threads you invalidate the cache, because the other thread is working on a different area of the memory. This basically erases the benefit of the cache. If you fill the whole array sequentially with one thread, you allow the processor's memory access optimizations to work as they were designed to work.
@ebw1910 you asked how to fill an array with random numbers in multiple threads, not how to fill it faster. If speed is your goal, your best bet is to find a faster random number generator.
Regarding the usage of the Parallel.ForEach method, my recommendation is to always specify explicitly the MaxDegreeOfParallelism, through the parallelOptions parameter. A reasonable value for this property is Environment.ProcessorCount. Otherwise the Parallel.ForEach method uses all the available ThreadPool threads, saturating the ThreadPool until the source enumerable completes.
Rogn yes, your code enumerates 10 ranges in parallel. So if the ThreadPool has already available (or can create instantly on demand) at least 10 threads, it will not be saturated. Otherwise it will be saturated. If I run your code in my PC, that has 4 cores, the ThreadPool will most probably become saturated during the parallel execution.
|
2

In modern c#, you should almost never have to use Thread objects themselves-- they are fraught with peril, and there are other language features that will do the job just as well (see async and TPL). I'll show you a way to do it with TPL.

Note: Due to the problem of false sharing, you need to rig things so that the different threads are working on different memory areas. Otherwise you will see no gain in performance-- indeed, performance could get considerably worse. In this example I divide the array into blocks of 4,000 bytes (1,000 elements) each and work on each block in a separate thread.

using System.Threading.Tasks;

var array = new int[10000];
var offsets = Enumerable.Range(0, 10).Select( x => x * 1000 );
Parallel.ForEach( offsets, offset => {
    for ( int i=0; i<1000; i++ )
    {
        array[offset + i] = random.Next( -100,100 );
    }
});

That all being said, I doubt you'll see much of a gain in performance in this example-- the array is much too small to be worth the additional overhead.

3 Comments

Thank you very much!
@ebw1910 of course it is. You have multiple threads trying to use the same resource at the same time. The result is resource contention.
Reminder: the Random class is not thread-safe!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.