Почему параллель. [дублировать]C#

Место общения программистов C#
Ответить
Anonymous
 Почему параллель. [дублировать]

Сообщение Anonymous »

Описание
Я недавно проверял метод c# parallel.for в отношении условий гонок и проблем с состоянием обмена.
Чтобы проверить эти проблемы, я реализовал простое приложение C# консоли, которое всегда должно вернуть один и тот же результат (список, содержащий последовательность ровных чисел от 0 до 8). < /P>
Реализация использует «одновременную сумку» для хранения данных каждого запуска, который, согласно документации Microsoft, представляет собой структуру данных, которая представляет собой безопасную, безупречную коллекцию объектов. Тем не менее, несмотря на все мои усилия, если выполнены, возвращаемые списки имеют разные размеры и с разными элементами, указывающие на следующие проблемы: < /p>

[*] Каждый раз »параллельно. Для «вызывается данные, данные разбиваются по -разному между потоками; < /li>
В алгоритме существует условие гонки, которое влияет ;
Возможно, существует эффект закрытия (т.е. проблему совместного использования), который происходит между каждым временем «parallel.for». >
Как правило, я ожидаю краткого воспроизводимого результата между каждой итерацией теста. Каждая итерация теста должна вернуть последовательность, такую ​​как {0,2,4,6,8}. Стоит отметить, что порядок элементов в последовательности не должен иметь значения, учитывая природу параллельной обработки. Следовательно, для моего теста успешный результат считается правильным, если и только если все N -последовательности имеют одни и те же элементы независимо от порядка, в котором они хранятся в каждой последовательности. Это условие проверки (как упомянуто в комментариях из этого вопроса) может рассматриваться как установленная проверка равенства. < /P>
фрагмент кода < /H2>
using System.Collections.Concurrent;

var nTests = 1000;

Main(nTests);

static List Test(int init, int final)
{
var result = new ConcurrentBag();

Action aggregate = (value) =>
{
lock(result)
{
if (!result.Contains(value))
{
result.Add(value);
}
}
};

Func initializer = () => 0;

Func body = (i, state, threadAcum) =>
{
if (threadAcum > 0)
{
state.Break();
}
else
{
if (i % 2 == 0)
{
threadAcum += i;
}
}

return threadAcum;
};

Parallel.For(init,
final,
initializer,
body,
aggregate);

return result.ToList();
}

static void ValidateResults(List[] repetitions)
{
bool testIsASuccess = true;

for ( int first = 0 ; testIsASuccess && first < repetitions.Length ; first++ )
{
for ( int second = 0 ; testIsASuccess && second < repetitions.Length ; second++ )
{
var rep = repetitions[first];
var rep2 = repetitions[second];
if ( !Enumerable.SequenceEqual(rep.OrderBy(x => x), rep2.OrderBy(x => x)) )
{
Console.WriteLine("Routine not consistent");

Console.WriteLine($"rep[{first}]:{string.Join(',', rep)}");
Console.WriteLine($"rep[{second}]:{string.Join(',', rep2)}");

testIsASuccess = false;
}
}
}

if ( testIsASuccess )
{
Console.WriteLine("SUCCESS! Routine is consistent");
}
}

static void Main(int ntests)
{
var repetitions = new List[ntests];

for ( int i = 0 ; i < ntests ; i++ )
{
var result = Test(0,10);

repetitions = result;
}

ValidateResults(repetitions);
}
< /code>
обсуждение < /h2>
Как можно заметить после попытки испытания выше, возвращенные последовательности варьируются от {0,2,4,6,8} вверх к результатам только одного элемента (например, {20}). Это ясно указывает на то, что методы «инициализатора» и «агрегации» вызываются на разных частотах на каждую итерацию теста. Что касается предоставленной документации (см. Здесь), не следует ожидать различного поведения между изолированными выполнениями того же метода (в моем случае методом «тест»).


Подробнее здесь: https://stackoverflow.com/questions/794 ... ame-method
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»