Parallel loop in winrt - c#

for (int j = 0; j < 10; j++)
{
for (long i = 0; i < bound / 10; i++)
{
routeLine.Locations.Add(new Location
{
Latitude = ((BingMapsRESTService.Route)(r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[k][0],
Longitude = ((BingMapsRESTService.Route)(r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[k][1]
});
k++;
}
await Task.Delay(TimeSpan.FromMilliseconds(1));
Temp("Drawing Route (" + ((j * 10)/2).ToString() + "%)"); // to show progress,Temp sets text property of a textbox
}
Bound has value between 6000 to 10000. This loop takes time and hang the UI that's why i divided the loop into 10 parts and used task.delay.
Is it possible to run all ten loops in parallel? I can't use thread as I can't create object of Location class in new thread. It throws an error of task being marshaled by some another thread

Yes it is possible; you can use TPL and Parallel.ForEach:
TPL
Parallel.ForEach

Related

Matrix Multiplication with specific number of threads [duplicate]

This question already has answers here:
Thread parameters being changed
(2 answers)
Closed 6 years ago.
I am completely new in the field of multithreading. At the moment I am trying to implement a commandline program which is able to multiply two matrices of equal size. The main goal is that the user can enter a specific number of threads as a commandline argument and that the multiplication task is solved using exactly this number of threads.
My approach is based on the following java implementation which tries to solve a similar task: Java Implementation Matrix Multiplication Multi-Threading
My current state is the following one:
using System;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
static int rows = 16;
static int columns = 16;
static int[] temp = new int[rows*columns];
static int[,] matrixA = new int[rows, columns];
static int[,] matrixB = new int[rows, columns];
static int[,] result = new int[rows, columns];
static Thread[] threadPool;
static void runMultiplication(int index){
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
Console.WriteLine();
result[index, i] += matrixA[index, j] * matrixB[j, i];
}
}
}
static void fillMatrix(){
for (int i = 0; i < matrixA.GetLength(0); i++) {
for (int j = 0; j < matrixA.GetLength(1); j++) {
matrixA[i, j] = 1;
matrixB[i, j] = 2;
}
}
}
static void multiplyMatrices(){
threadPool = new Thread[rows];
for(int i = 0; i < rows; i++){
threadPool[i] = new Thread(() => runMultiplication(i));
threadPool[i].Start();
}
for(int i = 0; i < rows; i++){
try{
threadPool[i].Join();
}catch (Exception e){
Console.WriteLine(e.Message);
}
}
}
static void printMatrix(int[,] matrix) {
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
Console.Write(string.Format("{0} ", matrix[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
}
static void Main(String[] args){
fillMatrix();
multiplyMatrices();
printMatrix(result);
}
}
At the moment I have two problems:
My result matrix contains values which are far from a valid result
I do not know if I am on the right way according to my goal that a user can specify how many threads should be used.
I would be very grateful if anyone could guide me to a solution.
PS: I know there are existing posts which are similar to mine, but the main challenge in my post is to allow the user to set the number of threads which will then solve the matrix multiplication.
Linear algebra is a difficult place to begin with threads if you're new. I'd recommend learning about map/reduce first and implementing that in C#.
Imagine if you have just one core and you wanted to perform a long calculation. Multiple threads are scheduled by the operating system so that one does some work, then the next is giving a turn, etc. It's easy to do the thought experiment and figure out that context switching will make the problem go slower than the single threaded version. There's no true parallelization there.
The problem is that most linear algebra operations are not easily parallelizable. They aren't independent of each other. More threads than cores will not improve the situation and may make performance worse.
The best you can do is one thread per core and partitioning the matrix like this.
Here's a thought: Before you worry about multithreading, take your Matrix class and make sure that every single operation works properly with a single thread. There's no sense in worrying about multithreading if your code doesn't produce the right answers for a single thread. Get that working, then figure out how to partition the problem among multiple threads.

Strange behaviour in for loop with System.Threading.Tasks

I'm creating System.Threading.Tasks from within a for loop, then running a ContinueWith within the same loop.
int[,] referencedArray = new int[input.Length / 4, 5];
for (int i = 0; i <= input.Length/4; i += 2048)
{
int[,] res = new int[input.Length / 4, 5];
int[,] arrayToReference = new int[input.Length / 4, 5];
Array.Clear(arrayToReference, 0, arrayToReference.Length);
Array.Copy(input, i, arrayToReference, 0, input.Length / 4);
Task<Tuple<int[,], int>> test = Task.Factory.StartNew(() => addReferences(arrayToReference, i));
test.ContinueWith(t => { Array.Copy(t.Result.Item1, 0, referencedArray, t.Result.Item2, input.Length / 4); MessageBox.Show("yai", t.Result.Item2.ToString()); });
Array.Copy(res, 0, referencedArray, i, input.Length / 4);
where the addReference sbroutine is:
public Tuple<int[,],int> addReferences(int[,] input, int index)
{
for (int i = 0; i < 2048; i++)
{
for (int j = 0; j < i; j++)
{
if ((input[i, 0] == input[j, 0]) && (input[i, 1] == input[j, 1]) && (input[i, 2] == input[j, 2]) && (input[i, 3] == input[j, 3]))
{
input[i, 4] = (j - i);
}
}
}
}
return new Tuple<int[,],int>(input,index);
}
However, I am getting really strange results:
1.The index (generated from the loop counter when the task is started) somehow becomes too large. I initially thought that this was because the loop counter had incremented past its maximum, stopping the loop, but when the continueWith executed it used the new value. However, even when I send the loop counter's value to the task as index when it starts, the error persists. Edit: Solved
I made I mistake in the original count
2.For some reason fewer than expected tasks are actually completed (e.g. even though 85 tasks are expected to be created, based on a loop counter maximum of 160,000 divided by a iteration of 2,048 = 78, only 77 pop ups appeared) - Edit Checking the console, it's apparent that the loop counter got up until about 157,696 before suddenly stopping.
I'm really confused by Tasks and Threading, so if you could be of any assistance that would be really useful - thanks in advance.
Edit I've made the changes suggested by Douglas, which solved my first problem - I'm still stuck on the second.
This might not completely resolve the issues you're having, but as a starting point, you need to avoid the closure issue by copying your loop counter to an inner variable before referencing it in your anonymous method:
for (int i = 0; i <= input.Length/4; i += 2048)
{
// ...
int iCopy = i;
var test = Task.Factory.StartNew(() => addReferences(arrayToReference, iCopy));
// ...
}
See Jon Skeet's answer (particularly the linked article) for an explanation of why this is necessary.
Edit: Regarding your second problem, I suspect it might have to do with integer division. What is the value of input.Length for which you're expecting 85 iterations? You say that 174,000 divided by 2,048 should give 85, but in practice, it will give 84, since integer division causes results to be truncated.
Edit2: Another reason you're not seeing all expected iterations could be that your program is terminating without waiting for the tasks (which typically execute on background threads) to complete. Check whether waiting on the tasks resolves your issue:
List<Task> tasks = new List<Task>();
for (int i = 0; i <= input.Length/4; i += 2048)
{
// ...
var test = Task.Factory.StartNew(() => addReferences(arrayToReference, iCopy));
tasks.Add(test);
// ...
}
Task.WaitAll(tasks);

Why is await async so slow?

I finally got VS2012 and got a simple demo up and working to check out the potential performance boost of async and await, but to my dismay it is slower! Its possible I'm doing something wrong, but maybe you can help me out. (I also added a simple Threaded solution, and that runs faster as expected)
My code uses a class to sum an array, based on the number of cores on your system (-1) Mine had 4 cores, so I saw about a 2x speed up (2.5 threads) for threading, but a 2x slow down for the same thing but with async/await.
Code: (Note you will need to added the reference to System.Management to get the core detector working)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Management;
using System.Diagnostics;
namespace AsyncSum
{
class Program
{
static string Results = "";
static void Main(string[] args)
{
Task t = Run();
t.Wait();
Console.WriteLine(Results);
Console.ReadKey();
}
static async Task Run()
{
Random random = new Random();
int[] huge = new int[1000000];
for (int i = 0; i < huge.Length; i++)
{
huge[i] = random.Next(2);
}
ArraySum summer = new ArraySum(huge);
Stopwatch sw = new Stopwatch();
sw.Restart();
long tSum = summer.Sum();
for (int i = 0; i < 100; i++)
{
tSum = summer.Sum();
}
long tticks = sw.ElapsedTicks / 100;
long aSum = await summer.SumAsync();
sw.Restart();
for (int i = 0; i < 100; i++)
{
aSum = await summer.SumAsync();
}
long aticks = sw.ElapsedTicks / 100;
long dSum = summer.SumThreaded();
sw.Restart();
for (int i = 0; i < 100; i++)
{
dSum = summer.SumThreaded();
}
long dticks = sw.ElapsedTicks / 100;
long pSum = summer.SumParallel();
sw.Restart();
for (int i = 0; i < 100; i++)
{
pSum = summer.SumParallel();
}
long pticks = sw.ElapsedTicks / 100;
Program.Results += String.Format("Regular Sum: {0} in {1} ticks\n", tSum, tticks);
Program.Results += String.Format("Async Sum: {0} in {1} ticks\n", aSum, aticks);
Program.Results += String.Format("Threaded Sum: {0} in {1} ticks\n", dSum, dticks);
Program.Results += String.Format("Parallel Sum: {0} in {1} ticks\n", pSum, pticks);
}
}
class ArraySum
{
int[] Data;
int ChunkSize = 1000;
int cores = 1;
public ArraySum(int[] data)
{
Data = data;
cores = 0;
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
{
cores += int.Parse(item["NumberOfCores"].ToString());
}
cores--;
if (cores < 1) cores = 1;
ChunkSize = Data.Length / cores + 1;
}
public long Sum()
{
long sum = 0;
for (int i = 0; i < Data.Length; i++)
{
sum += Data[i];
}
return sum;
}
public async Task<long> SumAsync()
{
Task<long>[] psums = new Task<long>[cores];
for (int i = 0; i < psums.Length; i++)
{
int start = i * ChunkSize;
int end = start + ChunkSize;
psums[i] = Task.Run<long>(() =>
{
long asum = 0;
for (int a = start; a < end && a < Data.Length; a++)
{
asum += Data[a];
}
return asum;
});
}
long sum = 0;
for (int i = 0; i < psums.Length; i++)
{
sum += await psums[i];
}
return sum;
}
public long SumThreaded()
{
long sum = 0;
Thread[] threads = new Thread[cores];
long[] buckets = new long[cores];
for (int i = 0; i < cores; i++)
{
int start = i * ChunkSize;
int end = start + ChunkSize;
int bucket = i;
threads[i] = new Thread(new ThreadStart(() =>
{
long asum = 0;
for (int a = start; a < end && a < Data.Length; a++)
{
asum += Data[a];
}
buckets[bucket] = asum;
}));
threads[i].Start();
}
for (int i = 0; i < cores; i++)
{
threads[i].Join();
sum += buckets[i];
}
return sum;
}
public long SumParallel()
{
long sum = 0;
long[] buckets = new long[cores];
ParallelLoopResult lr = Parallel.For(0, cores, new Action<int>((i) =>
{
int start = i * ChunkSize;
int end = start + ChunkSize;
int bucket = i;
long asum = 0;
for (int a = start; a < end && a < Data.Length; a++)
{
asum += Data[a];
}
buckets[bucket] = asum;
}));
for (int i = 0; i < cores; i++)
{
sum += buckets[i];
}
return sum;
}
}
}
Any thoughts? Am I doing async/await wrong? I'll be happy to try any suggestions.
It's important to separate "asynchrony" from "parallelization". await is there to help make writing asynchronous code easier. Code that runs in parallel may (or may not) involve asynchrony, and code that is asynchronous may or may not run in parallel.
Nothing about await is designed to make parallel code faster. The purpose of await is to make writing asynchronous code easier, while minimizing the negative performance implications. Using await won't ever be faster than correctly written non-await asynchronous code (although because writing correct code with await is easier, it will sometimes be faster because the programmer isn't capable of writing that asynchronous code correctly without await, or isn't willing to put the time in to do so. If the non-async code is written well it will perform about as well, if not a tad better, than the await code.
C# does have support specifically for parallelization, it's just not specifically though await. The Task Parallel Library (TPL) as well as Parallel LINQ (PLINQ) have several very effective means of parallelizing code that is generally more efficient than naive threaded implementations.
In your case, an effective implementation using PLINQ might be something like this:
public static int Sum(int[] array)
{
return array.AsParallel().Sum();
}
Note that this will take care of efficiently partitioning the input sequence into chunks that will be run in parallel; it will take care of determining the appropriate size of chunks, and the number of concurrent workers, and it will appropriately aggregate the results of those workers in a manor that is both properly synchronized to ensure a correct result (unlike your threaded example) and efficient (meaning that it won't completely serialize all aggregation).
async isn't intended for heavy-duty parallel computation. You can do basic parallel work using Task.Run with Task.WhenAll, but any serious parallel work should be done using the task parallel library (e.g., Parallel). Asynchronous code on the client side is about responsiveness, not parallel processing.
A common approach is to use Parallel for the parallel work, and then wrap it in a Task.Run and use await on it to keep the UI responsive.
Your benchmark has a couple of flaws:
You are timing the first run which includes initialization time (loading class Task, JIT-compilation etc.)
You are using DateTime.Now, which is too inaccurate for timings in the millisecond range. You'll need to use StopWatch
With these two issues fixed; I get the following benchmark results:
Regular Sum: 499946 in 00:00:00.0047378
Async Sum: 499946 in 00:00:00.0016994
Threaded Sum: 499946 in 00:00:00.0026898
Async now comes out as the fastest solution, taking less than 2ms.
This is the next problem: timing something as fast as 2ms is extremely unreliable; your thread can get paused for longer than that if some other process is using the CPU in the background. You should average the results over several thousands of benchmark runs.
Also, what's going on with your number of core detection? My quad-core is using a chunk size of 333334 which allows only 3 threads to run.
On a quick look, the results are expected: your async sum is using just one thread, while you asynchronously wait for it to finish, so it's slower than the multi-threaded sum.
You'd use async in case you have something else to finish while it's doing its job. So, this wouldn't be the right test for any speed/response improvements.

Why do these tasks execute sequentially?

Why does the following code execute sequentially?
List<Task> tasks = new List<Task>();
for (int i = 0; i <= max; i += block)
{
if (i + block >= max)
tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
else
block = max - i;
}
Task.WaitAll(tasks.ToArray());
I have also tested a version of this using Parallel.Invoke; it, too, fails to execute in parallel. There's bound to be something I'm not understanding, but when I try Googling this, I mostly get instructions on how to force sequential execution.
As a response to one of the caveats given in an answer below, I have included the following method for reference:
static void Count(ref int counter, int num)
{
int localCounter = 0;
for (int i = 0; i < num; i++)
if (Coin()) localCounter++;
System.Threading.Interlocked.Add(ref counter, localCounter);
}
Edited again: Thank you all!
Just replace tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block))); with Console.WriteLine and debug your code.
You never create more than one task.
for (int i = 0; i <= max; i += block)
{
if (i + block >= max)
Console.WriteLine(i);
else
block = max - i;
}
why does the following code execute sequentially?
It doesn't, unless you have something within the Count method that's synchronizing access to a single resource. If it can be parallelized, then this will run in parallel.
If Count executes very quickly then you'll find that the tasks are finished faster than new tasks get scheduled, which is why they may all execute in order.
Seems to me there is something wrong with your loop/if statement:
for (int i = 0; i <= max; i += block)
{
if (i + block >= max)
tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
else
block = max - i;
}
If I am reading it right, you will only add a task if i + block >= max and you will only loop if i + block <= max (showing both the counter increase and the condition check). As such you will only add a task once.
In addition, you are changing block when you are not adding a task. I expect you want something more like the following, though I can not be sure without more code:
for (int i = 0; i <= max; i += block)
{
tasks.Add(Task.Factory.StartNew(() => Count(ref counter, block)));
if (i + block >= max) { block = max - i; }
}

How do I avoid out of memory exceptions when using PLINQ?

Hi and thanks for looking!
Background
I have a computing task that requires either a lot of time, or parallel computing.
Specifically, I need to loop through a list of about 50 images, Base64 encode them, and then calculate the Levenshtein distance between each newly encoded item and values in an XML file containing about 2000 Base64 string-encoded images in order to find the string in the XML file that has the smallest Lev. Distance from the benchmark string.
A regular foreach loop works, but is too slow so I have chosen to use PLINQ to take advantage of my Core i7 multi-core processor:
Parallel.ForEach(candidates, item => findImage(total,currentWinner,benchmark,item));
The task starts brilliantly, racing along at high speed, but then I get an "Out of Memory" exception.
I am using C#, .NET 4, Forms App.
Question
How do I tweak my PLINQ code so that I don't run out of available memory?
Update/Sample Code
Here is the method that is called to iniate the PLINQ foreach:
private void btnGo_Click(object sender, EventArgs e)
{
XDocument doc = XDocument.Load(#"C:\Foo.xml");
var imagesNode = doc.Element("images").Elements("image"); //Each "image" node contains a Base64 encoded string.
string benchmark = tbData.Text; //A Base64 encoded string.
IEnumerable<XElement> candidates = imagesNode;
currentWinner = 1000000; //Set the "Current" low score to a million and bubble lower scores into it's place iteratively.
Parallel.ForEach(candidates, i => {
dist = Levenshtein(benchmark, i.Element("score").Value);
if (dist < currentWinner)
{
currentWinner = dist;
path = i.Element("path").Value;
}
});
}
. . .and here is the Levenshtein Distance Method:
public static int Levenshtein(string s, string t) {
int n = s.Length;
int m = t.Length;
var d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
Thanks in advance!
Update
Ran into this error again today under different circumstances. I was working on a desktop app with high memory demand. Make sure that you have set the project for 64-bit architecture to access all available memory. My project was set on x86 by default and so I kept getting out of memory exceptions. Of course, this only works if you can count on 64-bit processors for your deployment.
End Update
After struggling a bit with this it appears to be operator error:
I was making calls to the UI thread from the parallel threads in order to update progress labels, but I was not doing it in a thread-safe way.
Additionally, I was running the app without the debugger, so there was an uncaught exception each time the code attempted to update the UI thread from a parallel thread which caused the overflow.
Without being an expert on PLINQ, I am guessing that it handles all of the low-level allocation stuff for you as long as you don't make a goofy smelly code error like this one.
Hope this helps someone else.

Categories

Resources