Чи можу я використовувати всі 4 ядра процесора Raspberry Pi?


11

Мені було цікаво, чи існує простий спосіб "включити" всі 100% ЦП, щоб я міг швидше запускати процеси (наприклад, розрахунки пітона).

1) Чи це можливо?

2) Чи є простий спосіб повернутися до нормального?

3) Чи є спосіб використовувати менше процесора за бажанням?

Я думаю про взаємодію командного рядка на зразок:

pi@raspberry:~ $ sudo turnOnFourCores python run.py


1
Коротка відповідь - Ні
Стів Робіллард

16
Довга відповідь - "Якби це було так просто, це було б за замовчуванням"
Тінь

18
Обидва ваші коментарі вводять в оману і можуть означати, що Pi має 4 ядра, але використовує лише 1. Краще відповідь - це те, що всі чотири ядра вже включені , але що Python (і будь-яка інша програма, з цього приводу) використовуватиме лише більше ніж 1 ядро, якщо вони не є багатопотоковими. Python все ще може ефективно застрягнути за допомогою єдиного ядра навіть із багатопотоковою трансляцією через глобальне блокування інтерпретатора, але це трохи виходить за рамки цього питання.
Sohcahtoa82

13
Для уточнення, я думаю, що в ОП є непорозуміння, як працюють багатоядерні процесори, а ваші відповіді лише підсилюють їх нерозуміння.
Sohcahtoa82

6
Найпростіший спосіб зробити програму Python швидше - переписати на складеній мові (або принаймні зробити критично важливими для часу завданнями, використовуючи модуль змінного струму).
Milliways

Відповіді:


21

За замовчуванням будь-який комп'ютер намагатиметься використовувати всі свої ядра, коли зможе. Однак досягти цього можна лише тоді, коли додаток є багатопоточним. Якщо це не (тобто сценарій Python, який не використовує threadingмодуль), він може використовуватись лише на максимум, одне ядро. Це дорівнює 25% процесора на чотирьохядерному процесорі. Якщо ви хочете змінити свій скрипт для використання декількох ядер, ви можете розділити свій обчислення на кілька частин і багатопотоково, як показано в документації на Python .

Оновлення:

Як відповів Анон , це не спрацює без роботи з GIL Python (Global Interpreter Lock). Це дозволяє одночасно працювати (здавалося б) завданням, але не дозволяє коду працювати через декілька ядер. Якщо ви використовуєте модулі, написані на C (наприклад, numpy), вони можуть дозволити вам використовувати декілька ядер, які оточують це обмеження. Крім того, якщо це не варіант, Python пропонує мультиобробку , що дозволяє виконувати будь-яке завдання на декількох ядрах.


Оновлення - що є правильним - пояснює, чому перша частина відповіді неправильна щодо Python. Ви обмежуєте це обмеження Python, лише записуючи модулі C або якусь компільовану мову, і тоді ви вже зовсім не пишете Python. Якщо продуктивність є критичною, правильна відповідь - перехід на компільовану мову. (Багатопроцесорна робота не однакова з точки зору використання ресурсів.)
Цегла

4
@ Brick Просто для того, щоб бути зрозумілим, компільована мова, безумовно, не є вимогою до належної багатопотокової читання в процесі роботи. Хек, навіть GIL Python є деталізацією реалізації (надається для популярного CPython) - є й інші інтерпретатори Python, які з радістю будуть багатопоточні, наприклад, Jython та IronPython.
Боб

4
Додавання до плутанини, Python буде скомпільовано; у випадку CPython він компілює в байт-код CPython, який запускається в CPM CPython. Для Jython він компілюється в байт-код Java, який запускається в JVM. І нарешті, IronPython компілюється в CIL, який спрямований на .NET виконання. Отже, "переходити на компільовану мову" для виступу насправді не має сенсу;)
marcelm

будь-який комп'ютер намагатиметься використовувати всі свої ядра, коли зможе. Насправді, він буде використовувати всі свої ядра (або робити що-небудь ще), коли йому сказано . Ця відмінність може здатися очевидною або навіть опікуватися досвідченим, але це здається, що ОП повинна розуміти, що це не відбувається автоматично.
некоматичний

13

Мені було цікаво, чи існує простий спосіб "включити" всі 100% ЦП, щоб я міг швидше запускати процеси (наприклад, розрахунки пітона).

Не в тому сенсі, який я думаю, ви це маєте на увазі. Це не питання, характерне для пі, або це логічне обмеження.

Наразі самі комп’ютери не мають великої спроможності визначити, що процес, що працює як один потік, замість цього може запускатися паралельно. Зауважте, що в момент, коли вони можуть мати цю ємність, комп'ютерних програмістів не буде потреби, оскільки комп'ютерна система, яка могла б це зробити, може також написати власний код 1 .

Розглянемо наступний простий математичний вираз:

(4 + 2) * 17 / (3 + 6)

Існує певний потенціал, щоб це можна було обчислити паралельно, але він логічно обмежений. Я б сказав, що немає сенсу в більш ніж двох потоках, і навіть тоді це здебільшого лише одна:

#1 a) 4 + 2 b) 6 * 17 c) 102 / 9
#2 a) 3 + 6

Нитка №2 внесла свій внесок, обчисливши 3 + 6 = 9, що використовується на кроці С за допомогою потоку №1, зберегти його на один крок. Але це настільки, наскільки паралелізм корисно дістанеться тут. У той час як нитка №2 може обчислити 17/9, коли # 1 робить 6 * 17, це робити було б безглуздо, тому що тепер у вас є два різні шляхи до тієї самої мети, які неможливо відновити. Тобто, №2 може продовжувати працювати:

b) 17 / 9 c) 1.888 * 6

І в кінцевому рахунку з тим самим результатом, що і тема №1 (11.333), але вони не допомогли один одному за кроком А, тому наявність двох з них для досягнення цієї мети є марною витратою часу.

(Зверніть увагу, що цей приклад не є буквальним; він має намір продемонструвати логічний принцип. Шкала, за якою завдання вбудовані в код користувача, набагато більша, але вам не потрібен реальний урок багатопотокового програмування для того, щоб зрозуміти цю ідею тут.)

Для використання декількох процесорів потрібен код, написаний для цього. Ви не можете просто взяти нічого і сказати: "О, використовуйте всі 4 ядра і робіть це швидше!". Це не те, що станеться. За логікою, багато (... або більшість) проблем і завдань пов'язані з кроками, які не можуть відбуватися паралельно, вони повинні відбуватися послідовно.


1. Але дивіться коментар Фелікса Домбека нижче; Я не є експертом з ШІ. Можливо, варто також зазначити, що відповідно до коментарів Пітера Корда, ОС може використовувати сучасні набори інструкцій та процесори для оптимізації дуже дрібнозернистих речей паралельно, і апаратні трубопроводи роблять це також, хоч і не через ядра (єдине core має більше ніж одне, що працює в потоці інструкцій в різних точках до їх остаточного виконання). Я намагався тут дотримуватися теми теми користувача, оскільки я думаю, що це більш-менш те, що ви отримуєте.


4
Я написав багато паралельних числових кодів, і це трохи вводить в оману щодо деталей. Ви не здійснюєте паралелі на рівні окремих арифметичних дій, як це. (Якщо ми розширимось за межами Raspberry Pi, деякі компілятори та процесори вже все-таки паралелізуватимуть частину цього навіть поза структурами різьблення.) Ви паралелізуєте цілі завдання великими шматками.
Цегла

4
@Brick "Ви не паралелізовуєтеся на рівні окремих арифметичних дій, як це." -> Звичайно, ви цього не робите, але я зроблю більш очевидним, що це аналогія, а не урок багатопрофільного програмування гайок і болтів.
золотинки

4
Паралелізм у обчисленнях, які ви використовуєте як приклад, настільки локалізований, що він створить паралелізм рівня інструкцій у програмі, яка його обчислює, а процесори з виконанням поза замовленням можуть використовувати цей паралелізм самостійно.
Пітер Кордес

2
RPi3 використовує 2-широкий надскалярний en.wikipedia.org/wiki/ARM_Cortex-A53 , тому при ретельному плануванні інструкцій компілятор може все-таки використовувати ILP, поставивши дві addінструкції поруч, щоб вони могли працювати однаково тактовий цикл. Наступний режим множення та ділення буде розподілений залежно від даних, однак, як ви вказуєте.
Пітер Кордес

1
Визначення паралелізованих частин не обов'язково вимагає сильного AI. У «загальному» розумінні це може бути; але легко уявити, що комп'ютери могли використовувати якийсь евристичний підхід, який здебільшого працює в багатьох практичних випадках. Мовляв, комп’ютер не довів останню теорему Ферма, але, безумовно, є програми, що підтверджують теорему. Зауважимо, що сучасні компілятори для мов програмування вже роблять багато перестановки коду в рамках своїх кроків оптимізації, що включає міркування щодо паралелізованих частин.
Фелікс Домбек

7

Ні для пітона.

Інші люди пропонують вам розглянути нитки, що є коректною відповіддю для більшості мов, але вони не взяли до уваги, що ви використовуєте python.

Пітон GIL не дозволяє ефективно використовувати декілька ядер.


4
GIL робить його трохи більш складно використовувати всі 4 ядра. Ні в якому разі це не робить неможливим, а то й справді таким складним.
Підроблене ім’я

5

Використання декількох ядер вимагає явного виявлення паралелізму рівня потоку в ОС, що зазвичай вимагає від програміста написати багатопотокової програми. (Або запускати однопоточну програму кілька разів на різних входах, як-от компіляція make -j4)

Однак компілятори для деяких мов підтримують автоматичну паралелізацію. Наприклад, C або C ++ з OpenMP може скласти звичайний for()цикл у програму, яка запускає кілька потоків.

#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
   A[i] = B[i] * constant + C[i];
}

Але все-таки це має статися, коли ви писали або складали програму. Немає можливості для поточного обладнання та ОС використовувати кілька ядер для прискорення однопотокової програми.


Пов'язане: Як одна нитка працює на декількох ядрах? : відповідь: вони ні. Але існують і інші види паралелізму, як -от паралелізм на рівні інструкцій, який одне ядро ​​CPU знаходить і використовує для запуску одного потоку швидше, ніж одна інструкція одночасно.

Моя відповідь на це питання полягає в деяких деталях того, як сучасні процесори знаходять і використовують дрібнозернистий паралелізм на рівні інструкцій. (Здебільшого фокусується на x86). Це лише частина того, як працюють звичайні процесори, маючи декілька інструкцій під час польоту одночасно, і це не те, що потрібно спеціально включати. (Існують лічильники продуктивності, за допомогою яких можна побачити, скільки інструкцій за годинник вдалося виконати процесору під час виконання програми, хоча й інших заходів.)

Зауважте, що RPi3 використовує порядок процесорних ядер ARM Cortex-A53 . Кожне ядро ​​- це 2-широкий суперскаляр (2 інструкції на годинник, як дозволяє ILP), але не може переупорядкувати інструкції, щоб знайти більше паралелізму на рівні інструкцій та приховати затримку.

Все-таки процесор є конвеєрним, тому загальна кількість інструкцій в польоті (від вибору та декодування аж до етапу списання в кінці конвеєра) є значною. Якщо залежність від даних не обмежує можливості, на кожному етапі конвеєра, над яким працює центральний процесор, можуть бути дві інструкції з пропускною здатністю 2 інструкції на добу. (Ось що означає 2-широке значення.)

Він не може виконувати інструкції не в порядку, але при ретельному упорядкуванні інструкцій (як правило, компілятором), він все ще може приховати затримку інструкції, яка потребує декількох циклів, щоб її вихід був готовий. (наприклад, завантаження, навіть якщо воно потрапляє в кеш-пам'ять або множина, займе декілька циклів, порівняно з тим, що наступний цикл буде готовий). Трюк полягає в тому, щоб замовити інструкції asm, щоб існувало кілька незалежних інструкцій між тією, яка створює результат, і тією, яка її використовує.

Наявність програмного забезпечення (компілятора) статичних інструкцій для планування є більш крихким, ніж обладнання, яке може здійснювати внутрішній впорядкування, зберігаючи ілюзію виконання програмного порядку. Компіляторам дуже важко виконати таку роботу, як навіть невелике вікно поза замовленням для впорядкування інструкцій, оскільки помилки кешу непередбачувані, і важко проаналізувати ланцюги залежностей між функціональними викликами під час компіляції. А кількість реєстрів обмежена без апаратного реєстру-перейменування.


Все це - малий комфорт, коли ваш код працює повільніше, ніж вам би хотілося. Звичайно, у Cortex-A53 є багато класних речей під кришкою, але в Cortex-A57 є більше цікавих матеріалів під капотом (як, наприклад, виконання до 3 інструкцій на годинник поза замовленням) і навіть більше в великий процесор x86 на зразок Skylake (не кажучи вже про відмінності тактових частот).

Cortex-A53 є досить фантастичним порівняно з https://en.wikipedia.org/wiki/Classic_RISC_pipeline, як оригінальні MIPS, про які ви дізналися б у класі комп'ютерної архітектури, але за сучасними мірками це досить низько.


1
"У поточних апаратних та ОС не існує можливості використовувати кілька ядер для прискорення однопотокової програми." не суворо істинно. Наприклад, в одній потоковій програмі Java, Java може робити все, що стосується GC, та аналіз / компіляцію під час виконання додаткових ядер процесора. Аналіз виконання - це велика справа, оскільки він може вирішити зробити деякі оптимізації на основі запущених кодових шляхів, не витрачаючи нічого на "єдиний потік" і може значно прискорити те, що він дізнається з аналізу. Взагалі, хоча ваша думка хороша.
Білл К

@BillK Чесно кажучи, "програма" в цьому контексті є java, ні myapp.jar, і це, звичайно, не є єдиною ниткою.
goldilocks

1
Щоправда, я просто вказував, що залежно від того, як було розроблено час виконання, "код, який ви пишете", навіть не маючи однопотокової передачі, може скористатися додатковими ядрами, не чітко кодуючи його як багатопотокове додаток. Python також міг би забезпечити більш потужний час виконання, але це було б безглуздо. Це все-таки не величезний стрибок - я думаю, що навіть java використовує лише додатковий 1/2 ядра, щоб допомогти з одним додатком з потоком.
Білл К

" Немає можливості для поточного обладнання та ОС використовувати декілька ядер для прискорення однопотокової програми. " І відразу після цього ви поясните, як апаратне забезпечення виконує інструкції паралельно.
Томас Веллер

3
@ThomasWeller Так, але щоб бути вибагливим процесором, конвеєрне використання не використовує декілька ядер; він міститься в одному ядрі, але він дозволяє працювати в декількох потоках інструкцій. Тобто, це є однією з форм паралелізму, але це не є формою многоядерной різьблення.
goldilocks

4

Це не так, як працюють процесори ... взагалі.

На даний момент ваш процесор прекрасно здатний працювати на 100% використання, якщо припустити, що він не заглушений через проблеми, пов’язані з температурою при 80 градусах Цельсія або більше. При цьому, як правило, ви не хочете, щоб ваш процесор був прив'язаний до 100%. Якщо ви звичайно використовуєте 100% використання процесора, ви, ймовірно, матимете занадто багато для роботи процесора. Це спричинить заїкання і взагалі нещасний досвід користувачів.

Для порівняння з чимось більш фізичним, використання CPU дуже схоже на автомобіль. Автомобіль, швидше за все, здатний їхати 100 миль / год, але є хороший шанс, що ваш спідометр прочитає щось суттєве під цим. Перебуваючи в місті, ви ніколи не зможете отримати близько 25 миль / год. Але це не міняє, що автомобіль може їхати 100 миль / год. Ви просто недостатньо сильно натиснули на газ.

Якщо просто змусити RPi робити більше справ (натиснути більше на прискорювач), ви побачите, що цифра використання процесора зростає. Наприклад, спостерігайте за використанням процесора, коли ви запускаєте команду yesу вікні терміналу (пам'ятайте, що ctrl+cзакінчуються команди терміналу). Це збільшить ваш процесор на 25%, оскільки він збільшить один із чотирьох ядер CPU.


5
Я думаю, що ця відповідь вводить в оману, де, скажімо, ви, як правило, не хочете, щоб ваш процесор працював зі 100% використанням. Існує безліч чисельно інтенсивних додатків, де ви абсолютно хочете 100% використання, оскільки ви присвятили машині (або машинам) розрахунок. Щоб отримати справжній час на суперкомп'ютер, вам часто доводиться доводити, що ваш код достатньо оптимізований для цього, інакше вони відмовлять вам як марну трату ресурсів. Якщо у вас є кластер Pi, очевидно, ви не отримуєте суперпродуктивності комп'ютера, але це може зробити його більш критичним для максимального використання, не менше!
Цегла

3
Я якось погоджуюся з Brick в тому сенсі, що тут, мабуть, мається на увазі, що якщо процесор на 25%, це тому, що він повинен економити газ або дотримуватися обмеження швидкості;) або бути ввічливим, а не свинячим ресурсом. Можливо, ви хочете, щоб було зрозуміліше, що це взагалі тому, що будь-яка задача чекає на введення-виведення велику частину часу. Речі, які можуть виконувати єдине ядро ​​на весь шлях, будуть. Що (в ідеалі) перешкоджає цьому порушити користувальницький інтерфейс, це скорочення часу - але реально, все-таки досить легко заглушити невелику одноядерну машину.
золотинки

100% використання процесора, як правило, не спричиняє погану роботу UX. Навіть 1000% можуть бути досить хорошими, оскільки більшість програм не обмежені процесором, а іншими чинниками. Єдині програми, які стають повільними через екстремальне завантаження процесора - це програми, які фактично весь час користуються процесором.
Оскар скаго

4

Інші відповіді дають хороші деталі, але, схоже, не вирішують конкретні питання.

  1. Так, якщо програма (та операційна система) запрограмовані для обліку декількох ядер. ("Нитка" - це термін в програмуванні тут)
  2. Машина використовує стільки або мало кожного ядра, скільки потрібно для виконання завдання. тому не потрібно нічого змінювати.
  3. Ви можете встановити обмеження на максимальне використання, але немає необхідності в нормальному використанні. подивіться на відповіді тут: - /unix/151883/limiting-process-to-not-exceed-more-than-10-of-cpu-usage

Примітка:

Якщо ви хочете покращити ефективність пі загальної версії, ви можете заглянути в розгін. Це дозволяє процесору працювати швидше. Мінусами є збільшення виробництва тепла, менший термін експлуатації процесора та збільшення енергоспоживання.


2

Якщо можливо, я би параметризував сценарій та виконував їх в окремих процесах Python. Наприклад:

cat parameters.txt | xargs -n1 -P4 python run.py

Іншою альтернативою є вже згадана багатопроцесорна бібліотека, яка дозволяє розщеплювати і приєднуватися до процесів python. Але це також вимагає, щоб у вас був список параметрів (таких як ім'я файлу), для яких потрібно запускати обчислення.


Перша частина: Так, припускати, що проблема є незручно паралельною .
Пітер Мортенсен

Ага, правда, я був знайомий лише з багатопроцесорним процесорним пулом, mapале, мабуть, він також має багато досить складних конструкцій спільної пам'яті.
NikoNyrh

1

Я думаю, що ОП може не повністю зрозуміти поняття багатоядерного / багатопотокового програмування та наскільки складно повною мірою використовувати 100% багатоядерних, якщо алгоритм не може легко перетворитись у бентежно паралельну проблему.

Для отримання додаткової інформації ви можете прочитати більше про відому назву статті "Безкоштовний обід закінчився" http://www.gotw.ca/publications/concurrency-ddj.htm


0

Якщо ви хочете перевірити свій RPI. Можна запуститись stressяк тут , тоді ви зможете побачити, як використовуються ваші процесори htop. Це корисно, тому що ви можете бачити, чи достатньо джерела живлення, якщо його недостатньо, ваш RPI спробує використовувати занадто багато струму (силовий струм), і він вимкнеться.

З іншого боку, якщо ви хочете використовувати сценарій python, ви повинні побачити, joblibщо чудово працює, коли ви хочете паралелізувати процеси, і, таким чином, ви будете використовувати кількість бажаних процесорів.


0

Хоча всі ці відповіді правильні по-різному, це правда, що операційна система автоматично використовуватиме різні ядра для розподілу навантаження. Це можна побачити за допомогою простої програми python (temp.py say)

while True:
  x = 1.0

відкрийте термінал із робочого столу RPi та введіть, $ topде буде показана робота процесора. Потім відкрийте інший термінал, і python3 temp.pyви побачите, як робота python3 піднімається до 100% часу процесора. Потім відкрийте інший термінал і повторіть процес і подивіться, як ви рухаєтесь до 400%. Отож, на одному рівні, як прокоментував @Shadow, це просто і це за замовчуванням. Однак проектування програм, які можуть використовувати паралельну обробку, нетривіально, як пояснили інші.


0

Відповідь - гучна ТАК! Вам просто потрібно написати програму, щоб їх розпізнати та використовувати. Програми, які роблять це, можуть використовувати ядра. Я пишу своє, щоб зробити це на Java і, таким чином, можу.

Наведені вище відповіді розробників Python мають дуже обмежену концепцію цієї відповіді, і це може бути дуже заплутано, але відповідь ТАК і тільки ТАК!


Чи можете ви, будь ласка, докладно?
SDsolar

0

Оскільки ОП не вказав python у своєму питанні, я хотів би запропонувати ще дві сучасні мови, які добре працюють на Raspberry Pi і мають дуже прості способи використання одночасності.

Моя нинішня улюблена - мова Іржа. Я написав і склав програми на Pi. Іржа приємна тим, що вона запобігає багатьом типам помилок вказівників та перегонів, що робить написання одночасного коду простішим та безпечнішим. Іржа призначена системою мови програмування, але вона може робити майже все, що може зробити C.

Ще одна така мова - Go (також її називають Golang, щоб полегшити пошук). Go був створений командою Google і є досить зрілою мовою. Зробити супроводи в програмі Go, які вони називають "Go rutines", легко.

Обидві ці мови можуть скласти код на Raspberry Pi, навіть Pi Zero. Однак вони можуть бути складені між собою з більш швидкого комп'ютера, що приємно для великих програм.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.