Question

I have a Pentium(R) Dual Core CPU E5200 2/50GHz.

It means that I have two cores. I have developed a parallel approach for an Intelligent algorithm.

I am doing a data parallelism by splitting the data set into X parts (X = number of .net Tasks). I am giving a group of data to each task.

I have tried using 2, 4, 8 and 16 tasks and I couldnt see any improvement in the algorithm. Of course that parallel approach of the algorithm is faster then the serial (original) one but starting from 2 tasks up to 16 there is no improvement. They all perform same. I dont know weather Im doing something wrong or maybe the CPU capacity is that much (and it doesnt matter what the number of tasks is ?).

In order to be more practical, here is some of my code that describes what Im actually doing:

  while (iteration < SOMState.Map.numbOfIterations)
        {
            netTasks.Clear(); // netTaks contains all the tasks that I creat inside the loop
            int tdd = 0;
            foreach (TasksData td in tasks)
            {
                int val = tdd;
                Task t1 = Task.Factory.StartNew(() => startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val]));
                netTasks.Add(t1);
                tdd++;
            }

         await Task.WhenAll(netTasks);
         // do some stuff here
         iteration++;
        }


    public void startParallelMethod(int iteration,TasksData task,List<GenerateDataSetFromCSV.Vector> dataset, Map map, Dictionary<int, List<Double>> dictionaryDataset)
    {
        // it performs some processing in here
    }

Does one task use one core of processor?

Environment.ProcessorCount gives me 2. Does this mean that whatever is the number of tasks, still the performance will be as if I have used 2 tasks ?!

UPDATE:

For those who may be interested, I have answered to my own question.

Was it helpful?

Solution

As follow-up to the comments: Unless I'm missing something, instead of

int tdd = 0;
foreach (TasksData td in tasks)
{
    int val = tdd;
    Task t1 = Task.Factory.StartNew(() => startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val]));
    netTasks.Add(t1);
    tdd++;
}

you could write (please note: pseudo code!)

Parallel.For(0, tasks.Length, val => { 
    startParallelMethod(iteration, tasks[val], SOMState.dataset.GroupedData[val], tasks[val].Map, SOMState.dataset.GroupedDataDictionary[val])
});

As your original code uses await you could wrap the Parallel.For code in a Task.Run() and its behavior should be the same outside the method (although this is, same as your initial sample, far away from best practice on using async-await).

Nevertheless - with few changes you should be able to let the Runtime decide how many tasks to use.

OTHER TIPS

For those who may be interested:

After performing some experiments, here are the results using a core i7 processor. It shows up that using 6 tasks (the number of cores of processor) performs fastest. When I say using 6 tasks I also mean splitting my data set into 6 groups; each group will be given to one task. We can also use Parallel.For as the answer which I accepted suggests.

Table of results

In the image the results are shown for different data sets (different number of inputs). Starting from 5000 up to 100000 input data and for different number of tasks. You can easily find out (from the table, or you can try by yourself) that if you use Environment.ProcessorCount tasks performs fastest.

As a conclusion, results has shown that using Environment.ProcessorCount is a good practice. Each .NET task will than handle (independently from the programmer) the number of threads that it is going to create (under the hood).

P.S. Environment.ProcessorCount returns integer value (the number of cores of your processor). "Groups Of Data" means also number of tasks created

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top