Параллельная обработка JVM с потоками или пулом потоков на самом деле не работаетJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Параллельная обработка JVM с потоками или пулом потоков на самом деле не работает

Сообщение Anonymous »

Итак, мы тестируем параллельные потоки, и пока они вообще не дают никакого прироста производительности на 8-ядерной машине.

Код: Выделить всё

Optional ret = Arrays.stream( a ).parallel()
.mapToObj( source -> { some very heavy number crunching } )
.min( Comparator.comparing( s -> s.valueDelta ) );
Массив a имеет длину 4 и содержит числа 0...3.
Я могу «.peek()» и распечатать поток и увидите, что он использует 4 потока.
Время выполнения немного медленнее, чем замена потока последовательным циклом for, итерирующим по a.
Обработка чисел не имеет никаких операций ввода-вывода, взаимодействия, синхронизации и доступа. только структура данных только для чтения чтобы определить наилучшее значение «обмена».
Просто в качестве эксперимента я заменил обработку чисел на сон (2000), и все это завершилось через 2039 мс, так что, похоже, оно работает параллельно. Но обработка чисел совсем не ускоряется.
Если посмотреть с помощью проводника процессов и монитора ресурсов в Windows, кажется, что он использует только одно ядро.
Поэтому я попробовал запустить его на Linux и не получил лучших результатов.
По какой-то причине jvm неправильно использует доступные ядра при своей многопоточности.
Мы можем воспроизвести это на нескольких машинах, в Windows и Linux. и никто никогда получил какое-либо ускорение.
В качестве альтернативы я также реализовал его, используя фиксированный пул потоков размером 4, и снова, никакого ускорения, пока показаны 4 потока (я печатаю изнутри шаг для отладки, чтобы увидеть, есть ли у меня другой поток при параллельной печати).
Есть идеи?
РЕДАКТИРОВАТЬ Обновления после дополнительного тестирования:< /p>
После этого у меня появилось еще несколько идей тестирование:
Вы можете воспроизвести его, выполнив следующее как «перебор чисел». Я использовал 4 списка-массива, которые я перетасовал и отсортировал (это аналог моего кода, поскольку я использовал некоторые другие типы списков).

Код: Выделить всё

Optional ret = Arrays.stream( arrayOfLists ).parallel()
.mapToObj( list-> {
Collections.shuffle( list );
list.sort( comparator );
return list.get(0);
} )
.min();
Теперь, если перетасовка и сортировка одного списка занимает меньше, чем, скажем, 30 секунд, я не вижу никаких улучшений от парализации. Таким образом, независимо от того, распараллеливаю ли я, выполнение занимает 2 минуты.
Но если я сделаю списки достаточно длинными, скажем, 1 000 000 элементов, то я начну замечать некоторое увеличение скорости. Если я правильно помню, последовательно четыре списка занимают около 7 минут, а с 4 потоками или параллельными потоками - около 5 (также используя 4 потока, как я проверял).
Не опережайте меня по точным цифрам времени... было что-то около этого.
Теперь причина этого, по-видимому, в том, что операционная система (Windows и Linux) не считает рабочую нагрузку достаточно высокой, чтобы перемещать потоки на разные ядра, что безумие.
Если у меня нет списков настолько больших, что они занимают около минуты, вся работа выполняется только одним ядром, в то время как остальная часть моего 8-ядерного процессора спит.
p>
Теперь в моей исходной задаче я разбивал граф на минимальные пересекающиеся ребра (несколько разбиений), используя производную Лина-Кернигана.
Оценку всех возможных ходов можно легко разделить на непересекающиеся операции на запуск раздел подкачки.
Поэтому я хотел это пареллизовать. Но поскольку эта работа занимает для всех (в моем случае (4 раздела) около 1,5 с, операционная система отказывается пареллизовать мои потоки JVM, и поэтому я получаю нулевое ускорение.
И это это совершенно безумие, потому что весь алгоритм работает примерно на 18000 узлах и занимает в общей сложности от 5 до 10 минут.
Почти 20 лет назад ОС планировалось более разумно. Я защитил магистерскую диссертацию по реалистичному прогнозированию производительности параллельных алгоритмов, и тогда вы могли бы получить почти линейное увеличение скорости для независимых задач ОЧЕНЬ малого размера.
Теперь вопрос:
Так ли это? Планировщики ОС делают эту ерунду только с виртуальными машинами Java, или это общий регресс в планировании?
Могу ли я что-то с этим поделать? Я фактически испорчу множество параллельных алгоритмов, отказываясь это делать? запускайте их параллельно.

Подробнее здесь: https://stackoverflow.com/questions/792 ... eally-work
Ответить

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

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

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

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

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