Как java поток выбирает ядро процессора?
Вопрос — каждый поток привязывается к какому-то конкретному ядру или же в процессе исполнения программы может исполняться на другом ядре?
Я предполагаю, что при создании потока он привязывается к какому-то ядру, так как все объекты(не volatile), созданные этим потоком появляются в L1 кэше процессора. Как я понял, ядра имеют доступ только к своему L1 кэшу, а если поток будет исполняться на другом ядре, то он не увидит свои объекты, которые находятся в кэше другого ядра
Я правильно мыслю?
ни джава ни твоя программа никак не распределяет потоки процессов.
это отдельная служба ядра ОС — Диспетчер операционной системы.
как реализовано выбор проца для исполнения смотри в тех.документации на ОС.
обычно потоки не привязаны к процессорам, что есть свободное туда и пихают.
Вообще-то MatLab (на Java) может распараллелить задачу на все ядра. Но это невидимая процедура низкого уровня.
Александр Скуснов, он может через АПИ менеджера дать ему некоторые разрешенные наставления по управлению: ограничить количество используемых процов для задачи, выбрать процы и т.д. и т.п.
но напрямую ничего сделать не сможет. к такому пользовательские процессы в ОС не допускаются.
читай описание АПИ в ОС.
матлаб может распаралелить задачу хоть на сколько потоков исполнения.
но количество процов регулируется менеджером в соответствии с приоритетом процесса.
если появится процесс с высоким приоритетом и забьет собой все процы, то матлаб со всеми потоками скромненько задвинут в угол пока процы не освободятся.
есть такое прикольное приложение distcc оно разделяет задачу компиляции на кучу потоков и раскидывает по свободным компутерам в твоей сети. т.е. он использует все процы не тольк твоего компутера а еще и кучи соседних.
Блог
У меня есть программа, которая сортирует большие файлы, разбивая их на фрагменты, сортируя фрагменты и объединяя их в окончательный отсортированный файл. Приложение запускает один поток для загрузки / сохранения данных из / в файл — только один поток выполняет операции ввода-вывода. Также есть еще два потока, которые получают фрагментные данные, сортируют их, а затем отправляют отсортированные данные обратно в поток, который выполняет ввод-вывод.
Таким образом, в целом выполняется 4 потока — основной поток, поток, который загружает / сохраняет данные, и два потока, которые сортируют данные.
Я думал, что во время выполнения я увижу 1 спящий поток (основной), который не требует никакого процессорного времени, и 3 активных потока, которые используют по 1 ядру процессора каждый.
Когда я запускаю эту программу на двухъядерном процессоре с 6 ядерными процессорами с hyper threading (24 процессора), я вижу, что ВСЕ 24 процессора загружены на 100%!
Изначально я думал, что алгоритм сортировки многопоточен, но после изучения источников Java я обнаружил, что это не так.
Я использую simple Collections.sort(LinkedList) для сортировки данных…
вот некоторые подробности:
# java - версия версия java "1.6.0_26" Среда выполнения Java (TM) SE (сборка 1.6.0_26-b03) 64-разрядная серверная виртуальная машина Java HotSpot (TM) (сборка 20.1-b02, смешанный режим) # uname -a Linux 2.6.32-28-server # 55-Ubuntu SMP Пн Янв 10 23:57:16 UTC 2011 x86_64 GNU / Linux
Я использовал nmon для мониторинга загрузки процессора.
Я был бы признателен за любое объяснение этого случая и любые советы о том, как контролировать загрузку процессора, поскольку эта конкретная задача не оставляет процессорного времени для других приложений
[ОБНОВЛЕНИЕ] Я использовал jvisualvm для подсчета потоков — он показывает только потоки, о которых я знаю. Также я создал простую тестовую программу (см. Ниже), которая запускает только один основной поток и получила точно такие же результаты — все 24 процессора заняты почти на 100% во время выполнения кода public class Test < public void run()< Random r = new Random(); int len = r.nextInt(10) 5000000; LinkedList list = new LinkedList(); for (int i=0; inew String("test" r.nextInt(50000000))); > System.out.println("Inserted " list.size() " items"); list.clear(); > public static void main(String[] argv)< Test t = new Test(); t.run(); System.out.println("Done"); > >
[ОБНОВЛЕНИЕ] Вот снимок экрана, который я сделал во время запуска программы выше (используется nmon):
http://imageshack.us/photo/my-images/716/cpuload.png /
Комментарии:
1. Вероятно, нам нужно просмотреть ваш код, чтобы понять это. Я предполагаю, что вы используете больше потоков, чем думаете.
2. Я использовал jvisualvm для подсчета потоков — он показывает только потоки, о которых я знаю. Также я создал простую тестовую программу, которая запускает только один основной поток и получила точно такие же результаты. пожалуйста, ознакомьтесь с моим обновлением, о котором идет речь.
3. 4 потока не могут использовать 100%-ную загрузку 6 ядер. Либо у вас больше потоков, либо ваши измерения неверны.
4. Какую программу вы используете для мониторинга загрузки процессора? Вероятно, он показывает вам какую-то другую программу, которая работает в фоновом режиме. Либо это, либо ваш тест настолько короткий, что он показывает вам только что-то, связанное с запуском JVM.
5. Я использовал nmon для мониторинга загрузки процессора, вот скриншот: ссылка Также, пока я не запускаю программу Java — она не показывает никакой активности. Во всяком случае, я вижу то же самое при запуске моей оригинальной программы сортировки. Честно говоря, я ожидал именно того, чего все ожидали бы — один поток использует один процессор. но похоже, что java использует зеленые потоки, которые не связаны с базовыми потоками ОС. Насколько я понимаю, java использует собственное планирование потоков. Таким образом, это может привести к тому, что несколько собственных потоков будут обслуживать один поток Java.
Ответ №1:
Я бы предположил, что это скорее вопрос nmon, чем Java, и чтобы решить его, я бы взглянул на top команду, которая предоставляет информацию об использовании процессора для каждого процесса. Я предсказываю следующий результат: вы увидите, что один поток Java использует около 100% процессорного времени (что нормально, поскольку процентное соотношение между процессами в top относительно одного (виртуального) ядра), возможно, второй и третий потоки Java с гораздо меньшим использованием ЦП (потоки ввода-вывода). В зависимости от выбора gc вы можете даже обнаружить один или несколько gc-потоков, однако намного меньше 20.
Однако HotSpot не будет (и даже не может, насколько мне известно) самостоятельно распараллеливать последовательную задачу.
Комментарии:
1. Я проверил приложение с помощью «top -H», и там было много потоков, принадлежащих java. Затем я проверил приложение с помощью «jstack» во время выполнения и обнаружил там большое количество потоков gc: «Поток задач GC # 0» …. «Поток задач GC # 14» Итак, я считаю, что загрузка, показанная nmon, была сгенерирована потоками GC. Я прочитаю больше о том, как управлять GC. @Jonathan спасибо, что вернулся с идеей GC, у тебя есть мой голос
2. Я использовал -XX:ParallelGCThreads для управления количеством потоков и получил точно ожидаемые результаты в nmon — 4 потока приложений использовали 4 ядра. @Джонатан, еще раз спасибо!
Как включить все ядра процессора при выполнении кода
Решил запустить у себя эту программу. Залез в диспетчер задач и увидел, что у меня грузит данная вещь на 100 процентов только один процессор.
У меня шесть процессоров. В диспетчере задач указано, что нагрузка на процессор данной программой составляет 17 процентов. 100/6 приблизительно равна 17.
Поэтому возникла гипотеза, что Java у меня грузит только одно ядро из шести.
Я использую IntelliJ IDEA 2016, можно ли там включить опцию, чтобы были задействованы все ядра?
Как правильно обработать ошибки при выполнении кода?
Имеется код : public void addMedication(Set<ReservationMedication> reservationMedications) < .
Как включить ядра процессора?
Здравствуйте! AMD A8-3850 четырёх ядерный Один раз отключил два ядра через msconfig. Теперь не.
Как включить все ядра?
Всем привет, помогите пожалуйста включить все ядра. У меня стоит Intel Core i3 4160, у него 2 ядра.
Программы используют не все ядра процессора
Всем привет! Проблема в следующем у меня стоит Intel Core i5 4670 на материнке asus h81m-e. И.
Thread[] threads = new Thread[Runtime.getRuntime().availableProcessors()]; for (int i = 0; i threads.length; i++) { threads[i] = new Thread(() -> { for (;;) {} }); } for (Thread thread : threads) { thread.start(); }