Обработка массива потоками - C#
Формулировка задачи:
здравствуйте, подскажите пожалуйста, почему обработка массивов в потоке медленнее, чем последовательная обработка. Прошу пожалуйста, гляньте код, может я в чем-то ошиблась. Для параллельной обработки массив разбивается на диапазоны равные кол-ву потоков.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
// заполнение массива СВ
private static double[] GetDoubleArr(int size)
{
var result = new double[size];
var j1 = 1.01;
var j2 = 0.01;
for (var i = 0; i < size; i++)
{
result[i] = j1 +j2 ;
j1++;
j2=j2+0.01;
}
return result;
}
// возведение в степень
private static void PrlArr(double[] a, int threadcount)
{
var b = new double [100000];
int k = a.Length/threadcount;
int kInc = a.Length % threadcount;
Thread[] th = new Thread[threadcount];
// делим массив
int i1 = 0;
for (int i = 0; i < threadcount; i++)
{
int i2, i3;
if (i < kInc)
{
i2 = i1;
i3 = i1 + k + 1;
i1 += k + 1;
}
else
{
i2 = i1;
i3 = i1 + k;
i1 += k;
}
th[i] = new Thread((obj) =>
{
for (int j = i2; j < i3; j++)
{
b[j] = Math.Pow(a[j], 1.789);
}
});
th[i].Start();
}
for (int i = 0; i < threadcount; i++)
{
th[i].Join();
}
}
// возведение в степень
private static void PowerArr(double[] a)
{
double[] b = new double[a.Length];
for (var i = 0; i < a.Length; i++)
{
b[i] = Math.Pow(a[i], 1.789);
}
}
private static void PowerArrK(double[] a, int koef)
{
double[] b = new double[a.Length];
for (var i = 0; i < a.Length; i++)
{
for (var j = 0; j < koef; j++)
{ b[i] = Math.Pow(a[i], 1.789);
}
}
}
private static void Main(string[] args)
{
int[] n = {10, 100, 1000, 100000};
int[] m = {2, 3, 4, 5, 10};
// стоим векторы, заполняя значениями
List<double[]> A = n.Select(t => GetDoubleArr(t)).ToList();
// последовательная обработка
Console.Write("Введите кол-во прогонов вычисляемой функции - ");
// кол-во прогонов вычисляемой функции
int avg = Convert.ToInt32(Console.ReadLine());
Console.Write("Введите параметр сложности - ");
// кол-во прогонов вычисляемой функции
int k = Convert.ToInt32(Console.ReadLine());
// холостой запуск
PrlArr(A[0], m[0]);
PowerArrK(A[0], k);
PowerArr(A[0]);
Console.WriteLine("================================================================");
Console.WriteLine("Последовательная обработка - простая ");
Stopwatch sw = new Stopwatch();
TimeSpan ts;
for (var i = 0; i < n.Length; i++)
{
Console.WriteLine("Кол-во элементов в массиве - {0}", n[i]);
sw.Restart();
for (var j = 0; j < avg; j++)
{
PowerArr(A[i]);
}
sw.Stop();
ts = sw.Elapsed;
Console.WriteLine("Общее время: {0} миллисекунд", ts.TotalMilliseconds);
}
Console.WriteLine("================================================================");
Console.WriteLine("Последовательная обработка - усложненная ");
for (var i = 0; i < n.Length; i++)
{
Console.WriteLine("Кол-во элементов = {0}", n[i]);
sw.Restart();
for (var j = 0; j < avg; j++)
{
PowerArrK(A[i], k);
}
sw.Stop();
ts = sw.Elapsed;
Console.WriteLine("Общее время: {0} миллисекунд", ts.TotalMilliseconds / avg);
}
Console.WriteLine("================================================================");
Console.WriteLine("Параллельная обработка - простая ");
// цикл по потокам
for (var i = 0; i < n.Length; i++)
{
Console.WriteLine("Кол-во элементов = {0}", n[i]);
for (var l = 0; l < m.Length; l++)
{
Console.Write("Кол-во потоков - {0}. ", m[l]);
//sw = Stopwatch.StartNew();
// цикл для поиска ср. времени
sw.Restart();
for (var j = 0; j < avg; j++)
{
PrlArr(A[i], m[l]);
}
sw.Stop();
ts = sw.Elapsed;
Console.WriteLine("Общее время: {0} миллисекунд", ts.TotalMilliseconds / avg);
}
}
Console.ReadKey();
}
}
}Решение задачи: «Обработка массива потоками»
textual
Листинг программы
int threads = 5;
Parallel.For(0, threads, thread =>
{
while (thread < a.Length)
{
a[thread] = Math.Pow(a[thread], 1.789);
thread += threads;
}
});