Correctly parallelising lots of little tasks within a method using C#.NET












0















I'm implementing image processing algorithms in C# using .NET Framework 4.72 and need to decrease the computation code. Overall the code is sequential but there are quite a few methods with parameters that do not depend on each other. For example, it might be something like this



public void Algorithm(Object x, Object y) {    
x = Filter(x);
x = Morphology(x);
y = Filter(y);
y = Morphology(y);
var z = Add(x,y);

//Similar pattern of separate operation that are then combined.
}


These functions generally take around 100ms to 500ms. They can be parallelised, and my approach has been something like this:



public void Algorithm(Object x, Object y) {  
var xTask = Task.Run(() => {
x = Filter(x);
x = Morphology(x);
});
var yTask = Task.Run(() => {
y = Filter(y);
y = Morphology(y);
});
Task.WaitAll(xTask, yTask);
var z = Add(x,y);
}


It seems to work, a similar bit of code runs approximately twice as fast. (Note that the whole thing is wrapped in another Task.Run in the top most level function, so that is why I'm not awaiting here.



Question: Is this a valid approach, or is there another method for parallelising lots of little method calls that is more safe or efficient?



Update: This is not for parallelising processing a batch of images. It is about processing a single image as quick as possible.










share|improve this question

























  • try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

    – Hassaan
    Nov 20 '18 at 17:06






  • 1





    Try TPL DataFlow

    – Peter Bons
    Nov 20 '18 at 17:06






  • 1





    Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

    – Dan Rayson
    Nov 20 '18 at 17:09













  • @PeterBons Thanks - TPL DataFlow looks interesting.

    – geometrikal
    Nov 20 '18 at 17:12
















0















I'm implementing image processing algorithms in C# using .NET Framework 4.72 and need to decrease the computation code. Overall the code is sequential but there are quite a few methods with parameters that do not depend on each other. For example, it might be something like this



public void Algorithm(Object x, Object y) {    
x = Filter(x);
x = Morphology(x);
y = Filter(y);
y = Morphology(y);
var z = Add(x,y);

//Similar pattern of separate operation that are then combined.
}


These functions generally take around 100ms to 500ms. They can be parallelised, and my approach has been something like this:



public void Algorithm(Object x, Object y) {  
var xTask = Task.Run(() => {
x = Filter(x);
x = Morphology(x);
});
var yTask = Task.Run(() => {
y = Filter(y);
y = Morphology(y);
});
Task.WaitAll(xTask, yTask);
var z = Add(x,y);
}


It seems to work, a similar bit of code runs approximately twice as fast. (Note that the whole thing is wrapped in another Task.Run in the top most level function, so that is why I'm not awaiting here.



Question: Is this a valid approach, or is there another method for parallelising lots of little method calls that is more safe or efficient?



Update: This is not for parallelising processing a batch of images. It is about processing a single image as quick as possible.










share|improve this question

























  • try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

    – Hassaan
    Nov 20 '18 at 17:06






  • 1





    Try TPL DataFlow

    – Peter Bons
    Nov 20 '18 at 17:06






  • 1





    Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

    – Dan Rayson
    Nov 20 '18 at 17:09













  • @PeterBons Thanks - TPL DataFlow looks interesting.

    – geometrikal
    Nov 20 '18 at 17:12














0












0








0








I'm implementing image processing algorithms in C# using .NET Framework 4.72 and need to decrease the computation code. Overall the code is sequential but there are quite a few methods with parameters that do not depend on each other. For example, it might be something like this



public void Algorithm(Object x, Object y) {    
x = Filter(x);
x = Morphology(x);
y = Filter(y);
y = Morphology(y);
var z = Add(x,y);

//Similar pattern of separate operation that are then combined.
}


These functions generally take around 100ms to 500ms. They can be parallelised, and my approach has been something like this:



public void Algorithm(Object x, Object y) {  
var xTask = Task.Run(() => {
x = Filter(x);
x = Morphology(x);
});
var yTask = Task.Run(() => {
y = Filter(y);
y = Morphology(y);
});
Task.WaitAll(xTask, yTask);
var z = Add(x,y);
}


It seems to work, a similar bit of code runs approximately twice as fast. (Note that the whole thing is wrapped in another Task.Run in the top most level function, so that is why I'm not awaiting here.



Question: Is this a valid approach, or is there another method for parallelising lots of little method calls that is more safe or efficient?



Update: This is not for parallelising processing a batch of images. It is about processing a single image as quick as possible.










share|improve this question
















I'm implementing image processing algorithms in C# using .NET Framework 4.72 and need to decrease the computation code. Overall the code is sequential but there are quite a few methods with parameters that do not depend on each other. For example, it might be something like this



public void Algorithm(Object x, Object y) {    
x = Filter(x);
x = Morphology(x);
y = Filter(y);
y = Morphology(y);
var z = Add(x,y);

//Similar pattern of separate operation that are then combined.
}


These functions generally take around 100ms to 500ms. They can be parallelised, and my approach has been something like this:



public void Algorithm(Object x, Object y) {  
var xTask = Task.Run(() => {
x = Filter(x);
x = Morphology(x);
});
var yTask = Task.Run(() => {
y = Filter(y);
y = Morphology(y);
});
Task.WaitAll(xTask, yTask);
var z = Add(x,y);
}


It seems to work, a similar bit of code runs approximately twice as fast. (Note that the whole thing is wrapped in another Task.Run in the top most level function, so that is why I'm not awaiting here.



Question: Is this a valid approach, or is there another method for parallelising lots of little method calls that is more safe or efficient?



Update: This is not for parallelising processing a batch of images. It is about processing a single image as quick as possible.







c# .net task-parallel-library






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 17:16







geometrikal

















asked Nov 20 '18 at 16:46









geometrikalgeometrikal

9422927




9422927













  • try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

    – Hassaan
    Nov 20 '18 at 17:06






  • 1





    Try TPL DataFlow

    – Peter Bons
    Nov 20 '18 at 17:06






  • 1





    Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

    – Dan Rayson
    Nov 20 '18 at 17:09













  • @PeterBons Thanks - TPL DataFlow looks interesting.

    – geometrikal
    Nov 20 '18 at 17:12



















  • try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

    – Hassaan
    Nov 20 '18 at 17:06






  • 1





    Try TPL DataFlow

    – Peter Bons
    Nov 20 '18 at 17:06






  • 1





    Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

    – Dan Rayson
    Nov 20 '18 at 17:09













  • @PeterBons Thanks - TPL DataFlow looks interesting.

    – geometrikal
    Nov 20 '18 at 17:12

















try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

– Hassaan
Nov 20 '18 at 17:06





try to explore Task.Factory for more detailed task creation. Also try to explore the shared context in tasks. I don't know what x,y,z is. If it is a reference type object then this code is a killer in parallel/multithread programming

– Hassaan
Nov 20 '18 at 17:06




1




1





Try TPL DataFlow

– Peter Bons
Nov 20 '18 at 17:06





Try TPL DataFlow

– Peter Bons
Nov 20 '18 at 17:06




1




1





Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

– Dan Rayson
Nov 20 '18 at 17:09







Parallel.ForEach( //do stuff )? docs.microsoft.com/en-us/dotnet/standard/parallel-programming/… Literally designed for easy parallel operations :)

– Dan Rayson
Nov 20 '18 at 17:09















@PeterBons Thanks - TPL DataFlow looks interesting.

– geometrikal
Nov 20 '18 at 17:12





@PeterBons Thanks - TPL DataFlow looks interesting.

– geometrikal
Nov 20 '18 at 17:12












1 Answer
1






active

oldest

votes


















0














This is valid enough - if you can process your workload in parallel then you should. You just need to be very aware of WHEN your workload can and should be parallel - and when it needs to be performed in order.



You also need to consider the cost of creating a new task, versus the benefits of doing so (i.e. sometimes avoid very small, very fast tasks).



I would strongly recommend you create additional methods and collections for managing your tasks - when they complete, and handle running lots of separate sets in parallel. Avoiding locking, managing shared memory/variables etc. For example, are you only ever processing one image at a time, or can you start processing the next one if you have cores available?



You need to be very careful with Task.WaitAll() - obviously you need to draw all your work together at some point, but be careful not to lock or block other work.



There's lots of articles out there on the various patterns you can use (pipelines sounds like a good match here).



Here's a few starters:



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism






share|improve this answer
























  • When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

    – geometrikal
    Nov 20 '18 at 17:15













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397708%2fcorrectly-parallelising-lots-of-little-tasks-within-a-method-using-c-net%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














This is valid enough - if you can process your workload in parallel then you should. You just need to be very aware of WHEN your workload can and should be parallel - and when it needs to be performed in order.



You also need to consider the cost of creating a new task, versus the benefits of doing so (i.e. sometimes avoid very small, very fast tasks).



I would strongly recommend you create additional methods and collections for managing your tasks - when they complete, and handle running lots of separate sets in parallel. Avoiding locking, managing shared memory/variables etc. For example, are you only ever processing one image at a time, or can you start processing the next one if you have cores available?



You need to be very careful with Task.WaitAll() - obviously you need to draw all your work together at some point, but be careful not to lock or block other work.



There's lots of articles out there on the various patterns you can use (pipelines sounds like a good match here).



Here's a few starters:



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism






share|improve this answer
























  • When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

    – geometrikal
    Nov 20 '18 at 17:15


















0














This is valid enough - if you can process your workload in parallel then you should. You just need to be very aware of WHEN your workload can and should be parallel - and when it needs to be performed in order.



You also need to consider the cost of creating a new task, versus the benefits of doing so (i.e. sometimes avoid very small, very fast tasks).



I would strongly recommend you create additional methods and collections for managing your tasks - when they complete, and handle running lots of separate sets in parallel. Avoiding locking, managing shared memory/variables etc. For example, are you only ever processing one image at a time, or can you start processing the next one if you have cores available?



You need to be very careful with Task.WaitAll() - obviously you need to draw all your work together at some point, but be careful not to lock or block other work.



There's lots of articles out there on the various patterns you can use (pipelines sounds like a good match here).



Here's a few starters:



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism






share|improve this answer
























  • When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

    – geometrikal
    Nov 20 '18 at 17:15
















0












0








0







This is valid enough - if you can process your workload in parallel then you should. You just need to be very aware of WHEN your workload can and should be parallel - and when it needs to be performed in order.



You also need to consider the cost of creating a new task, versus the benefits of doing so (i.e. sometimes avoid very small, very fast tasks).



I would strongly recommend you create additional methods and collections for managing your tasks - when they complete, and handle running lots of separate sets in parallel. Avoiding locking, managing shared memory/variables etc. For example, are you only ever processing one image at a time, or can you start processing the next one if you have cores available?



You need to be very careful with Task.WaitAll() - obviously you need to draw all your work together at some point, but be careful not to lock or block other work.



There's lots of articles out there on the various patterns you can use (pipelines sounds like a good match here).



Here's a few starters:



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism






share|improve this answer













This is valid enough - if you can process your workload in parallel then you should. You just need to be very aware of WHEN your workload can and should be parallel - and when it needs to be performed in order.



You also need to consider the cost of creating a new task, versus the benefits of doing so (i.e. sometimes avoid very small, very fast tasks).



I would strongly recommend you create additional methods and collections for managing your tasks - when they complete, and handle running lots of separate sets in parallel. Avoiding locking, managing shared memory/variables etc. For example, are you only ever processing one image at a time, or can you start processing the next one if you have cores available?



You need to be very careful with Task.WaitAll() - obviously you need to draw all your work together at some point, but be careful not to lock or block other work.



There's lots of articles out there on the various patterns you can use (pipelines sounds like a good match here).



Here's a few starters:



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming



https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/potential-pitfalls-in-data-and-task-parallelism







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 '18 at 17:09









Phil SPhil S

1789




1789













  • When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

    – geometrikal
    Nov 20 '18 at 17:15





















  • When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

    – geometrikal
    Nov 20 '18 at 17:15



















When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

– geometrikal
Nov 20 '18 at 17:15







When processing a set of images I normally put all the work in Parallel.ForEach etc. In this case, the program interacts with a machine which waits on the result of the image processing before it can continue, so I have to try to parallelise within the method as much as possible.

– geometrikal
Nov 20 '18 at 17:15




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53397708%2fcorrectly-parallelising-lots-of-little-tasks-within-a-method-using-c-net%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory