Я играю с Parallel.ForEach в консольном приложении C#, но, похоже, не может быть прав. Я создаю массив со случайными числами, и у меня есть последовательный foreach и Parallel.ForEach, который находит наибольшее значение в массиве. Примерно с тем же кодом в C++ я начал видеть компромисс с использованием нескольких потоков при значениях 3M в массиве. Но Parallel.ForEach в два раза медленнее даже при значениях 100M. Что я делаю не так?Parallel.ForEach медленнее, чем обычно, foreach
class Program
{
static void Main(string[] args)
{
dostuff();
}
static void dostuff() {
Console.WriteLine("How large do you want the array to be?");
int size = int.Parse(Console.ReadLine());
int[] arr = new int[size];
Random rand = new Random();
for (int i = 0; i < size; i++)
{
arr[i] = rand.Next(0, int.MaxValue);
}
var watchSeq = System.Diagnostics.Stopwatch.StartNew();
var largestSeq = FindLargestSequentially(arr);
watchSeq.Stop();
var elapsedSeq = watchSeq.ElapsedMilliseconds;
Console.WriteLine("Finished sequential in: " + elapsedSeq + "ms. Largest = " + largestSeq);
var watchPar = System.Diagnostics.Stopwatch.StartNew();
var largestPar = FindLargestParallel(arr);
watchPar.Stop();
var elapsedPar = watchPar.ElapsedMilliseconds;
Console.WriteLine("Finished parallel in: " + elapsedPar + "ms Largest = " + largestPar);
dostuff();
}
static int FindLargestSequentially(int[] arr) {
int largest = arr[0];
foreach (int i in arr) {
if (largest < i) {
largest = i;
}
}
return largest;
}
static int FindLargestParallel(int[] arr) {
int largest = arr[0];
Parallel.ForEach<int, int>(arr,() => 0, (i, loop, subtotal) =>
{
if (i > subtotal)
subtotal = i;
return subtotal;
},
(finalResult) => {
Console.WriteLine("Thread finished with result: " + finalResult);
if (largest < finalResult) largest = finalResult;
}
);
return largest;
}
}
Я поставил параллельное выполнение в 5-ти раз в течение цикла и время выполнения отличаться друг от друга на 500 миллионов долларов. Может быть 100 мс или 10 секунд. – Christoph
Вы используете свой код в режиме отладки? По моему опыту, параллельные методы работают ужасно медленно, когда VS-отладчик подключен. Попробуйте создать Release и запустить exe-файл вместо запуска с VS. –
Каждый Parallel.ForEach разворачивает свою собственную задачу, поэтому да, это ухудшится. Вместо этого вы должны рассмотреть возможность использования Partitioner для разделения работы. Предложите размер блока 2 * Environment.ProcessorCount. См. Https://msdn.microsoft.com/en-us/library/system.collections.concurrent.partitioner(v=vs.110).aspx. –