Почему я получаю другую сумму при параллельном вызове с разным количеством потоков? - PullRequest
1 голос
/ 30 мая 2020

Это просто продолжение следующего вопроса, который я задал:

Почему я не могу достичь 100% загрузки ЦП с помощью кода параллельных задач?

 private static int SumParallel()
        {
            var intList = Enumerable.Range(1, 1000_000_000);
            int count = intList.Count();
            int threads = 6;
            List<Task<int>> l = new List<Task<int>>(threads);
            for(int i = 1; i <= threads; i++)
            {
                int skip = ((i - 1) * count) / threads;
                int take = count / threads;
                l.Add(GetSum(intList, skip, take));
            }
            Task.WaitAll(l.ToArray());
            return l.Sum(t => t.Result);
        }

private static Task<int> GetSum(IEnumerable<int> list, int skip, int take)
        {
            return Task.Run(() =>
             {
                 int temp = 0;
                 foreach(int n in list.Skip(skip).Take(take))
                 {
                     if (n % 2 == 0)
                         temp -= n;
                     else
                     {
                         temp += n;
                     }
                 }

                 Console.WriteLine(temp + " " + Task.CurrentId);
                 return temp;
             });
        }

Если я изменю количество задач, работающих параллельно, я получу другую сумму.

Почему это так?

1 Ответ

2 голосов
/ 30 мая 2020

Это из-за этой строки:

int skip = ((i - 1) * count) / threads;
int take = count / threads;

учитывайте threads = 3 и count = 10 Это не может охватить весь ваш список. В зависимости от количества потоков вы получаете разные округления в take и skip, и иногда они не могут охватывать все элементы в списке.

Возможно, вам стоит изменить это так:

for(int i = 1; i <= threads; i++)
{
    int skip = ((i - 1) * count) / threads;
    int take = count / threads;

    if(i == threads)
        take = threads - skip;

    l.Add(GetSum(intList, skip, take));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...