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!
Parallels offers a free trial period for Parallels Access. The trial period lasts for 14 days and cannot be extended.
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.
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.
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With