Reputation: 12814
I have a method that processeswords in two lists, a priority list and a standard list.
ConcurrentBag<Word> PriorityWords = ...;
ConcurrentBag<Word> UnprocessedWords = ...;
public void ProcessAllWords()
{
while (true)
{
Word word = SelectWordToProcess();
if (word == null) break;
ProcessWord(word);
}
}
private Word SelectWordToProcess()
{
Word word;
if (PriorityWords.TryTake(out word) || UnprocessedWords.TryTake(out word))
return word;
else
return null;
}
public void ProcessWord(Word word) { ... }
I want to run this method on multiple cores. Currently, I simply open one thread per processor:
for (int i = 0; i < Environment.ProcessorCount; i++)
{
new Thread(ProcessAllWords).Start();
}
Is there a more suitable way that lets the system decide how many threads to open based on current system performance, similar to Parallel.ForEach()
?
EDIT: More detail on the application.
The word list is prepopulated with ~180,000 words and every word is to be permutated with every other word. ProcessAllWords
is an O(n²) operation. The threads will all run flat-out until all words are processed, then terminate. While the threads are running, I can asynchronously give priority to specific words by adding them to the PriorityWords
list. Initial tests show my system processes about 5 words/sec, so that's 10 hours of 100% CPU processing.
Upvotes: 0
Views: 280
Reputation: 6352
Your method of starting Environment.ProcessorCount threads is good. The Task Parallel Library will do the automatic scheduling that you're looking for, but at the cost of over subscribing your CPU. This will decrease the responsiveness of your application to priority words.
As for the various methods of using TPL, parallel for and task factory will both queue up a bunch of words, making it very unresponsive to priority. You can maintain your priority with a generator method and PLINQ, but then you get a fixed number of threads as you have now. You can either set your thread count or use the default of 2xEnvironment.ProcessorCount. All in all, since your task is CPU bound, I would keep your current implementation.
Upvotes: 1