Eвклидова норма вектора с помощью метода Parallel.For и Parallel.Invoke - C#
Формулировка задачи:
Имеется прога (евклидова норма вектора)
Преобразовать её, чтобы распараллеливание шло методом методом Parallel.For и Parallel.Invoke
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Evklid
{
class Program
{
static void Main(string[] args)
{
var vector = new double[] { 2, 3, 4, 5, 6 }; // Вектор
var taskCount = 3; //Число параллельных задач
var sum = CalculateSum(vector, taskCount); //Параллельный подсчет суммы
var norm = Math.Sqrt(sum);
Console.WriteLine("Сумма квадратов: " + sum + "; Норма вектора: " + norm);
Console.ReadKey();
}
private static double CalculateSum(double[] vector, int taskCount)
{
var len = vector.Length;
//Не может быть задач больше числа элементов вектора
if (taskCount > len)
throw new ArgumentException();
var step = (len + 1) / taskCount; //Интервал для суммы
var tasks = new Task<double>[taskCount];
for (var i = 0; i < taskCount; i++)
{
tasks[i] = Task<double>.Factory.StartNew((obj) => Sum(vector, (int)obj * step, ((int)obj + 1) * step - 1), i);
}
Task.WaitAll(tasks);
var sum = tasks.Select(x => x.Result).Sum();
return sum;
}
static double Sum(IEnumerable<double> vector, int index1, int index2)
{
index2 = index2 >= vector.Count() ? vector.Count() : index2;
return vector.Skip(index1).Take(index2 - index1 + 1).Select(x => x * x).Sum();
}
}
}Решение задачи: «Eвклидова норма вектора с помощью метода Parallel.For и Parallel.Invoke»
textual
Листинг программы
static void Main(string[] args)
{
var vector = new double[] { 2, 2, 2, 2, 2 }; // Вектор
var sum = 0.0;
Parallel.ForEach(vector,
() => // Initializer
{
return 0.0;
},
(item, state, subtotal) => // Loop body
{
return subtotal += item*item;
},
(subtotal) => // Accumulator
{
lock (vector)
{
sum += subtotal;
}
});
var norm = Math.Sqrt(sum);
Console.WriteLine("Сумма квадратов: "+sum+"; Норма вектора: "+norm);
Console.ReadKey();
}