Почему в Kotlin / Java нет опции для приоритетного планировщика? - PullRequest
4 голосов
/ 07 августа 2020

Задача, связанная с тяжелым процессором, может блокировать поток и задерживать выполнение других задач, ожидающих выполнения. Это потому, что JVM не может прерывать запущенный поток и требует помощи программиста и прерывания вручную. Kotlin в коде ниже.

fun simple(): Sequence<Int> = sequence { // sequence builder
    for (i in 1..3) {
        Thread.sleep(100) // pretend we are computing it
        yield(i) // yield next value
    }
}

fun main() {
    simple().forEach { value -> println(value) } 
}

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

Но разве это не так. лучше будет переключатель, чтобы можно было выбирать? Если вы хотите запустить JVM с более быстрым планировщиком без вытеснения. Или с более медленным упреждающим ударом (прерывание и переключение протектора после N инструкций) один, но способный работать плавно и не требующий для этого ручного труда?

Интересно, почему Java / Kotlin не работает? У меня есть такой переключатель JVM, который позволял бы выбрать, какой режим вы хотите.

Ответы [ 2 ]

5 голосов
/ 07 августа 2020

Когда вы программируете с использованием Kotlin сопрограмм или Java виртуальных потоков (после Loom), вы получаете упреждающее планирование из ОС.

Следуя обычной практике, задачи, которые не выполняются заблокированные (т. е. им нужен ЦП), мультиплексируются по реальным потокам ОС в диспетчере Kotlin по умолчанию или Java ForkJoinPool. Эти потоки ОС планируются операционной системой с упреждением.

Однако, в отличие от многопоточности в старом стиле, задачи не назначаются потоку, когда они заблокированы в ожидании ввода-вывода. Это делает никакой разницы с точки зрения вытеснения, поскольку задача, ожидающая ввода-вывода, в любом случае не может вытеснить другую запущенную задачу.

Что вы не get при программировании с помощью сопрограмм - это упреждающее планирование большого количества задач одновременно. Если у вас есть много задач, требующих ЦП, то первые N будут назначены реальному потоку, а ОС будет их разрезать по времени. Остальные будут ждать в очереди, пока они не будут выполнены.

Но в реальной жизни, когда у вас есть 10000 задач, которые должны быть одновременно интерактивные , они связаны с задачами ввода-вывода. . В среднем не так много ресурсов, которым требуется процессор одновременно, поэтому количество реальных потоков, которые вы получаете от диспетчера по умолчанию или ForkJoinPool, достаточно. • 1017 интерактивный, ну, тогда вам все равно будет грустно, потому что квантование времени не обеспечит очень плавного взаимодействия.

5 голосов
/ 07 августа 2020

Этот вопрос основан на ложной предпосылке: В JVM вы можете выбрать только вытесняющий планировщик. Ни одна современная JVM не использует кооперативную многозадачность.

В современной JVM нет реализации пользователя космические потоки или собственный планировщик. Вместо этого JVM используют собственные потоки операционной системы. Собственные потоки планируются операционной системой, а планировщики операционной системы являются вытесняющими.

Тот факт, что потоки JVM сопоставляют 1-к-1 собственным потокам операционной системы, является проблемой для приложений, которые нужен высокий уровень параллелизма. Нитки относительно редки и дороги. Чтобы решить эту проблему, Project Loom изучает возможность добавления «виртуальных потоков», которые могут позволить использовать собственные потоки более экономно, особенно для задач, связанных с вводом-выводом.

Project Loom находится в активной разработке и там Нет установленного графика, когда он станет частью стандарта Java. Что касается того, как Project Loom планирует «виртуальные потоки», в последнем (май 2020 г.) обновлении от Project Loom утверждается «виртуальные потоки являются вытесняющими, а не кооперативными» , но затем продолжает говорить «ни один из планировщиков в JDK в настоящее время не использует вытеснение виртуальных потоков на основе временного интервала» . Похоже, что в своем текущем состоянии планировщик «виртуального потока» в Project Loom находится где-то между полностью кооперативным и полностью упреждающим. Будет интересно посмотреть, как будет развиваться проект и что мы получим, когда он будет интегрирован в основной поток Java.

В 28 июля Q&A упомянул руководитель проекта Loom Рон Пресслер что вы сможете подключить собственный планировщик для виртуального потока, но не go в деталях о том, какой контроль вы получаете над алгоритмом планирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...