Мне было интересно, есть ли простой способ «включить» все 100% ЦП, чтобы я мог быстрее запускать процессы (например, вычисления на python).
1) возможно ли это?
2) Есть ли простой способ вернуться к нормальной жизни?
3) Есть ли способ использовать меньше процессора при желании?
Я думаю о взаимодействии командной строки, как:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
Ответы:
По умолчанию любой компьютер будет пытаться использовать все свои ядра, когда это возможно. Тем не менее, он может достичь этого только тогда, когда приложение является многопоточным. Если это не так (т.е. скрипт Python, который не использует
threading
модуль), то он может использовать максимум одно ядро. Это соответствует 25% ЦП на четырехъядерном процессоре. Если вы хотите изменить свой сценарий для использования нескольких ядер, вы можете разделить вычисления на несколько частей и создать многопоточность, как показано в документации по Python .Обновить:
Как ответил Anon , это не сработает без работы с GIL Python (Global Interpreter Lock). Это позволяет задачам работать (казалось бы) одновременно, но не позволяет коду запускаться на нескольких ядрах. Если вы используете модули, написанные на C (например, numpy), они могут позволить вам использовать несколько ядер, чтобы обойти это ограничение. Кроме того, если это не вариант, Python предлагает многопроцессорность , которая позволяет запускать любые задачи на нескольких ядрах.
источник
Не в том смысле, что я думаю, что вы намекаете. Это не проблема, специфичная для pi, это логическое ограничение.
Сами по себе компьютеры в настоящее время не имеют достаточных возможностей для определения того, что процесс, работающий как один поток, может вместо этого выполняться параллельно. Обратите внимание, что в тот момент, когда они могут обладать такой способностью, компьютерным программистам не понадобится, потому что компьютерная система, которая может сделать это, может также написать свой собственный код 1 ..
Рассмотрим следующее простое математическое выражение:
Есть некоторый потенциал для этого, чтобы быть рассчитанным параллельно, но он логически ограничен. Я бы сказал, что нет смысла более чем в двух потоках, и даже тогда это в основном будет только один:
Поток № 2 внес свой вклад путем вычисления 3 + 6 = 9, использованного на шаге C потоком # 1, сохранив его на один шаг. Но это то, насколько параллелизм будет полезен здесь. В то время как поток № 2 мог бы вычислять 17/9, в то время как № 1 выполняет 6 * 17, делать это было бы бессмысленно, потому что теперь у вас есть два разных пути к одной и той же цели, которые невозможно объединить. То есть, # 2 может продолжать работать:
И в итоге получается тот же результат, что и в потоке № 1 (11.333), но они не помогли друг другу после шага А, поэтому выполнение двух из них для достижения этой цели - пустая трата времени.
(Обратите внимание, что этот пример не является буквальным; он предназначен для демонстрации логического принципа. Масштаб, в котором задачи пронизаны в пользовательском коде, намного больше, но вам не нужен реальный урок в многопоточном программировании, чтобы понять идею здесь.)
Для эксплуатации нескольких процессоров необходим код, который написан для этого. Вы не можете просто взять что-нибудь и сказать: «О, используйте все 4 ядра и делайте это быстрее!». Это не то, что случилось бы. Логично, что многие (или большинство) проблем и задач включают шаги, которые не могут происходить параллельно, они должны происходить последовательно.
1. Но см. Комментарий Феликса Домбека ниже; Я не эксперт по ИИ. Также стоит отметить, что, согласно комментариям Питера Корде, современные наборы команд и процессоры могут использоваться ОС для параллельной оптимизации очень мелкозернистых вещей, а аппаратные конвейеры также делают это, хотя и не по ядрам (один Ядро имеет более чем одну вещь, работая над потоком инструкций в различных точках перед их окончательным выполнением). Я пытался придерживаться темы пользовательских тем здесь, поскольку я думаю, что это более или менее то, что вы получаете.
источник
add
инструкции рядом друг с другом, чтобы они могли работать в одном и том же тактовый цикл. Следующее умножение и деление остатка будет сериализовано зависимостями данных, как вы указали.Нет для питона.
Другие люди предлагают вам изучить многопоточность, которая является правильным ответом для большинства языков, но они не приняли во внимание, что вы используете python.
Python GIL не позволяет эффективно использовать несколько ядер.
источник
Использование нескольких ядер требует явного раскрытия параллелизма на уровне потоков для ОС, что обычно требует от программиста написания многопоточной программы. (Или запускать однопотоковую программу несколько раз на разных входах, например, при компиляции
make -j4
)Однако компиляторы для некоторых языков поддерживают автоматическое распараллеливание. Например, C или C ++ с OpenMP могут скомпилировать обычный
for()
цикл в программу, которая запускает несколько потоков.Но все же это должно произойти, когда вы написали или скомпилировали программу. Современное оборудование и операционные системы не могут использовать несколько ядер для ускорения однопоточной программы.
Связанный: Как один поток работает на нескольких ядрах? : answer: они этого не делают. Но есть и другие виды параллелизма, такие как параллелизм на уровне инструкций, который одно ядро ЦПУ находит и использует для запуска одного потока быстрее, чем одна инструкция за раз.
Мой ответ на этот вопрос касается некоторых деталей того, как современные процессоры находят и используют детализированный параллелизм на уровне команд. (В основном с упором на x86). Это лишь часть того, как работают нормальные процессоры, когда в полете одновременно выполняется несколько инструкций, и это не то, что вам нужно специально включать. (Существуют счетчики производительности, которые позволяют увидеть, сколько инструкций за такт удалось выполнить вашему ЦП во время выполнения программы или других мер.)
Обратите внимание, что RPi3 использует процессорные ядра ARM Cortex-A53 . Каждое ядро имеет суперскалярную ширину 2 (2 инструкции за такт, как позволяет ILP), но не может переупорядочивать команды, чтобы найти больше параллелизма на уровне команд и скрыть задержку.
Тем не менее, ЦП конвейерно, поэтому общее количество команд в полете (от выборки и декодирования до стадии обратной записи в конце конвейера) является значительным. Когда зависимости данных не ограничивают, на каждом этапе конвейера, на котором работает ЦП, могут быть 2 инструкции с пропускной способностью 2 инструкции в такт. (Это то, что означает 2 в ширину.)
Он не может выполнять инструкции не по порядку, но при аккуратном упорядочении команд (обычно компилятором) он все еще может скрывать задержку команды, которая занимает несколько циклов для ее вывода, чтобы быть готовым. (например, загрузка, даже если она попадет в кэш или умножится, займет несколько циклов, а добавление будет готово в следующем цикле). Хитрость заключается в том, чтобы упорядочить ассемблерные инструкции, чтобы было несколько независимых инструкций между той, которая дает результат, и той, которая его использует.
Наличие программного обеспечения (компилятора) статически запланированных инструкций более хрупко, чем наличие оборудования, которое может переупорядочивать внутренне, сохраняя иллюзию работы в программном порядке. Компиляторам очень трудно выполнить такую же хорошую работу, как даже небольшое окно с неупорядоченным порядком для переупорядочения инструкций, потому что ошибки в кэше непредсказуемы, и трудно анализировать цепочки зависимостей между вызовами функций во время компиляции. И количество регистров ограничено без аппаратного переименования регистров.
Все это не очень удобно, когда ваш код работает медленнее, чем вам хотелось бы. Конечно, в Cortex-A53 под капотом много классных вещей, но в Cortex-A57 под капотом есть больше классных вещей (например, выполнение не по порядку до 3 инструкций за такт), и даже больше в большой процессор x86, такой как Skylake (не говоря уже о разнице в тактовой частоте).
Cortex-A53 довольно фантастичен по сравнению с https://en.wikipedia.org/wiki/Classic_RISC_pipeline, как оригинальные MIPS, о которых вы узнаете в классе компьютерной архитектуры, но по современным стандартам это довольно низкоуровневая версия.
источник
java
нетmyapp.jar
, и, конечно, она не однопоточная.Это не так, как работают процессоры ... вообще.
В настоящее время ваш процессор прекрасно способен работать на 100% при условии, что он не регулируется из-за проблем, связанных с температурой 80 градусов Цельсия или более. При этом, вы (как правило) не хотите видеть привязку вашего процессора к 100%. Если вы обычно используете процессор на 100%, вы, вероятно, слишком много для вашего процессора. Это приведет к заиканию и, как правило, к недовольству пользователей.
Если сравнивать с чем-то более физическим, то загрузка вашего процессора во многом напоминает автомобиль. Автомобиль, вероятно, способен развивать скорость 100 миль в час, но есть большая вероятность, что ваш спидометр что-то значительно из-за этого прочитает. Находясь в городе, вы никогда не сможете разогнаться до 25 миль в час. Это, однако, не меняет того, что машина может разгоняться до 100 миль в час. Вы просто не нажали на акселератор достаточно сильно.
Если вы просто заставите RPi делать больше вещей (больше нажимать на ускоритель), вы увидите, что показатель использования ЦП будет расти. Например, следите за загрузкой процессора, когда вы запускаете команду
yes
в окне терминала (помните, чтоctrl+c
команды терминала заканчиваются). Это увеличит ваш ЦП на 25%, так как оно увеличит одно из четырех ваших ядер ЦП.источник
Другие ответы дают хорошие детали, но, кажется, не обращаются конкретно к вашему вопросу (ам).
NB:
Если вы хотите улучшить производительность пи в целом, вы можете рассмотреть возможность разгона. Это позволяет процессору работать быстрее. Недостатками являются увеличение выработки тепла, сокращение срока службы процессора и увеличение энергопотребления.
источник
Если возможно, я бы параметризировал скрипт и выполнял их в отдельных процессах Python. Например:
Другой альтернативой является уже упоминавшаяся многопроцессорная библиотека, которая позволяет вам форк-и-присоединять процессы Python. Но для этого также требуется, чтобы у вас был список параметров (например, имя файла), для которых вы хотите выполнить вычисления.
источник
map
но, очевидно, он также имеет много довольно сложных конструкций с общей памятью.Я думаю, что OP, возможно, не полностью понимает концепции многоядерного / многопоточного программирования и насколько сложно полностью использовать 100% многоядерности, если алгоритм не может быть легко превращен в неловко параллельную проблему.
Для получения дополнительной информации, вы можете прочитать больше о хорошо известном заголовке статьи "Бесплатный обед окончен" http://www.gotw.ca/publications/concurrency-ddj.htm
источник
Если вы хотите проверить свой RPI. Вы можете запустить
stress
как здесь , тогда вы можете увидеть, как ваши процессоры используются сhtop
. Это полезно, потому что вы можете увидеть, достаточно ли вашего источника питания, если этого недостаточно, ваш RPI попытается использовать слишком большой ток (сила тока), и он отключится.С другой стороны, если вы хотите использовать сценарии Python, вы должны увидеть,
joblib
какой из них отлично работает, когда вы хотите распараллелить процессы, и, таким образом, вы будете использовать желаемое количество процессоров.источник
Хотя все эти ответы правильны по-разному, это правда, что операционная система будет автоматически использовать разные ядра для распределения нагрузки. Вы можете увидеть это с помощью простой программы на Python (скажем, temp.py)
откройте терминал с вашего рабочего стола RPi и введите,
$ top
который покажет работу процессора. Затем откройте другой терминал, иpython3 temp.py
вы увидите, что работа Python3 возрастает до 100% процессорного времени. Затем откройте другой терминал и повторите процесс и посмотрите, как вы двигаетесь до 400%. Так что на одном уровне, как прокомментировал @Shadow, все так просто, и это значение по умолчанию. Однако проектирование программ, которые могут использовать параллельную обработку, нетривиально, как объяснили другие.источник
Ответ звучит ДА! Вы просто должны написать свою программу, чтобы распознать их и использовать их. Программы, которые делают это, могут использовать ядра. Я пишу свой, чтобы сделать это на Java, и, таким образом, я могу.
Приведенные выше ответы от разработчиков Python имеют очень ограниченную концепцию этого ответа и поэтому могут быть очень запутанными, но ответ ДА и только ДА!
источник
Поскольку OP не указал python в своем вопросе, я хотел бы предложить еще два современных языка, которые прекрасно работают на Raspberry Pi и имеют очень простые способы использования параллелизма.
Мой текущий фаворит - язык Rust. Я написал и скомпилировал программы на Пи. Rust хорош тем, что он предотвращает многие типы ошибок указателя и состояния гонки, что делает написание параллельного кода более простым и безопасным. Rust предназначен для языка системного программирования, но он может делать практически все, что может делать C.
Другой такой язык - Go (также называется Golang, чтобы облегчить поиск). Go был создан командой Google и является достаточно зрелым языком. Легко сделать сопрограммы в Go, которые они называют «подпрограммами Go».
Оба эти языка могут компилировать код на Raspberry Pi, даже на Pi Zero. Тем не менее, они оба могут быть кросс-компилированы с более быстрого компьютера, что хорошо для больших программ.
источник