Описание
Я недавно проверял метод 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 ... tions-of-a
Почему параллель. [дублировать] ⇐ C#
Место общения программистов C#
1739545132
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[i] = result;
}
ValidateResults(repetitions);
}
< /code>
обсуждение < /h2>
Как можно заметить после попытки испытания выше, возвращенные последовательности варьируются от {0,2,4,6,8} вверх к результатам только одного элемента (например, {20}). Это ясно указывает на то, что методы «инициализатора» и «агрегации» вызываются на разных частотах на каждую итерацию теста. Что касается предоставленной документации (см. Здесь), не следует ожидать различного поведения между изолированными выполнениями того же метода (в моем случае методом «тест»).
Подробнее здесь: [url]https://stackoverflow.com/questions/79436956/why-parallel-for-is-not-consistent-between-different-aggregation-executions-of-a[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия