Welcome to MSDN Blogs Sign in | Join | Help

News

  • These postings are provided "AS IS" with no warranties and confer no rights. All code and tools presented are done so under the Microsoft Public License.
Custom Loop with Arbitrary Initialization, Condition, and Update

The Parallel.For loop construct provided by Parallel Extensions is focused on providing a parallel alternative to the common sequential pattern of a for loop that iterates over a range of numbers.  However, the for loop construct in a language like C# is not limited just to numbers and iterating over ranges.  It supports arbitrary initialization, condition, and update expressions, for example:

for(var i = init(); cond(i); i = upd(i)) { Use(i); }

There isn't any built-in Parallel construct that supports this pattern. However, one of our goals with Parallel Extensions is to provide the foundational support to add these types of constructs easily on top of what we do provide.  This is a good example of that.  Consider the following implementation:

public static void ParallelFor<T>(
    Func<T> init, Func<T,bool> cond, Func<T,T> upd, Action<T> body)
{
    Parallel.ForEach(Iterate(init, cond, upd), body); 
}

private static IEnumerable<T> Iterate<T>(
    Func<T> init, Func<T,bool> cond, Func<T,T> upd)
{
    for(var i=init(); cond(i); i = upd(i)) yield return i;
}

As you can see, it was straightforward to create a parallel For method that accepted arbitrary initialization, condition, and update expressions.  This was done by creating an iterator in C# for looping as was done in the original sequential example, and then passing the result of an invocation of that iterator to a call to Parallel.ForEach.  We can now use this construct.  For example, let's say I have a linked list of nodes, and I want to execute some substantial amount of code for every node in the list.  Sequentially, that might look like:

for(Node n = list; n != null; n = n.Next)
{
    Process(n);
}

With our new ParallelFor method, we can do the same thing in parallel:

ParallelFor(() => list, n => n != null, n => n.Next, n =>
{
    Process(n);
});

Simplicity.  Of course, there are many other ways the ParallelFor method could be implemented; building on top of Parallel.ForEach is just one of them.

Posted: Sunday, July 27, 2008 11:51 AM by toub

Comments

Pointernil said:

Hi there,

i just remembered what i was missing lately using parallel.for:

how about an override which allows for LONG indexes instead of INT. Yes, the current workaround is to use a cast, but that's ... ;)

# July 29, 2008 10:41 AM

toub said:

Pointernil, thanks for the request.  Support for In64 in Parallel.For is certainly something we're considering.  What are you doing that you need Int64s?  Is it that you are already using Int64 values but in the range of Int32 and are just trying to avoid a cast, or are you actually outside the bounds of what an Int32 can support?

# July 29, 2008 2:35 PM

Pointernil said:

@toub: 1) my index being typed with Long sneaked in by using FileStream.Seek method with large, sorry hudge files; this one takes a "long Offset" param;

2) PFX rocks!

3) Please have a serious talk with Anders or Mr.Erik Meijers ;) and have them wrap the lib with some syntactic sugar in the compilers.

4) When are you guys going to announce that OS level interface to co-processing units and the PFX support for that? ;)

# July 30, 2008 1:45 AM

toub said:

Pointernil, thanks for the feedback, and I'm very glad you find Parallel Extensions useful.  We're definitely considering Int64 support; others have suggested it's important, too.

As for Anders and Erik, we talk with them all the time :)

# August 1, 2008 9:26 PM

ZenPyrical said:

I am very much looking forward to the new .Net Parallel extensions being RTM&#39;d. This Post from Stephen

# August 9, 2008 7:03 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker