Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are you using Parallel Extensions? [closed]

I hope this is not a misuse of stackoverflow; recently I've seen some great questions here on Parallel Extensions, and it got my interest piqued.

My question: Are you using Parallel Extensions, and if so, how?

My name is Stephen Toub and I'm on the Parallel Computing Platform team at Microsoft. We're the group responsible for Parallel Extensions. I'm always interested in hearing about how developers are utilizing Parallel Extensions (e.g. Parallel.For, PLINQ, ConcurrentDictionary, etc.), positive experiences you've had, negative experiences you've had, feature requests for the future, and so on.
If you'd be willing to share such information, please do, either here as a response to this question or to me privately through email at stoub at microsoft dot com.

I'm very much looking forward to hearing from you.

Thanks in advance!

like image 596
Stephen Toub Avatar asked Oct 18 '10 14:10

Stephen Toub


People also ask

How long is parallel trial?

Parallels offers a free trial period for Parallels Access. The trial period lasts for 14 days and cannot be extended.

How does Parallels work on Mac?

How does Parallels Desktop work? To add Windows, Linux, or another operating system to your Mac, Parallels Desktop creates a virtual machine (VM)—a virtual PC inside your Mac. You can then install Windows on the virtual machine, just as you would install any operating system on a regular computer.

Is Parallels safe for Mac M1?

Parallels Desktop is designed to mimic the running of an operating system using a VM. And since Apple's newest Macs have replaced the Intel processor with M1 chips, many wonder whether Parallels is compatible with M1.


2 Answers

I'm using the TPL for doing nested Parallel.ForEach calls. Because I access dictionaries from these calls I have to use ConcurrentDictionary. Although it's nice, I have a few issues:

  • The delegates inside of ForEach don't do much work so I don't get much parallelism. The system seems to spend most of its time joining threads. It would be nice if there was a way to figure out why it's not getting better concurrency and improve it.

  • The inner ForEach iterations are over ConcurrentDictionary instances, which would cause the system to spend much of its time enumerators for the dictionary if I didn't add an enumerator cache.

  • Many of my ConcurrentDictionary instances are actually sets, but there is no ConcurrentSet so I had to implement my own with a ConcurrentDictionary.

  • ConcurrentDictionary does not support object initialization syntax so I can't say var dict = new ConcurrentDictionary<char, int> { { 'A', 65 } }; which also means I can't assign ConcurrentDictionary literals to class members.

  • There are some places where I have to lookup a key in a ConcurrentDictionary and call an expensive function to create a value if it doesn't exist. It would be nice if there were an overload of GetOrAdd that takes an addValueFactory so that the value can be computed only if the key doesn't exist. This can be simulated with .AddOrUpdate(key, addValueFactory, (k, v) => v) but that adds the overhead of an extra delegate call to every lookup.

like image 164
Gabe Avatar answered Oct 02 '22 03:10

Gabe


I haven't used it extensively yet, but I've definitely kept my ear to its uses and look for opportunities in our code base to put it to use (unfortunately, we're .NET-2.0 bound on many of our projects still for the time being). One little gem I came up with myself was a unique word counter. I think this is the fastest and most concise implementation I can come up with - if someone can make it better, that would be awesomeness:

private static readonly char[] delimiters = { ' ', '.', ',', ';', '\'', '-', ':', '!', '?', '(', ')', '<', '>', '=', '*', '/', '[', ']', '{', '}', '\\', '"', '\r', '\n' };
private static readonly Func<string, string> theWord = Word;
private static readonly Func<IGrouping<string, string>, KeyValuePair<string, int>> theNewWordCount = NewWordCount;
private static readonly Func<KeyValuePair<string, int>, int> theCount = Count;

private static void Main(string[] args)
{
    foreach (var wordCount in File.ReadAllText(args.Length > 0 ? args[0] : @"C:\DEV\CountUniqueWords\CountUniqueWords\Program.cs")
        .Split(delimiters, StringSplitOptions.RemoveEmptyEntries)
        .AsParallel()
        .GroupBy(theWord, StringComparer.OrdinalIgnoreCase)
        .Select(theNewWordCount)
        .OrderByDescending(theCount))
    {
        Console.WriteLine(
            "Word: \""
            + wordCount.Key
            + "\" Count: "
            + wordCount.Value);
    }

    Console.ReadLine();
}

private static string Word(string word)
{
    return word;
}

private static KeyValuePair<string, int> NewWordCount(IGrouping<string, string> wordCount)
{
    return new KeyValuePair<string, int>(
        wordCount.Key,
        wordCount.Count());
}

private static int Count(KeyValuePair<string, int> wordCount)
{
    return wordCount.Value;
}
like image 43
Jesse C. Slicer Avatar answered Oct 02 '22 05:10

Jesse C. Slicer