Як отримати 100% використання центрального процесора від програми C.


79

Це досить цікаве питання, тож дозвольте мені встановити сцену. Я працюю в Національному музеї обчислювальної техніки, і нам щойно вдалося придбати суперкомп’ютер Cray Y-MP EL з 1992 року, і ми справді хочемо побачити, як швидко він може йти!

Ми вирішили, що найкращий спосіб зробити це - написати просту програму на С, яка б обчислювала прості числа і показувала, скільки часу це потрібно, а потім запускала програму на швидкому сучасному настільному ПК та порівнювала результати.

Ми швидко придумали цей код для підрахунку простих чисел:

Що на нашому двоядерному ноутбуці під управлінням Ubuntu (The Cray працює UNICOS), працював ідеально, використовуючи 100% процесора і займаючи близько 10 хвилин. Повернувшись додому, я вирішив спробувати його на своєму сучасному ігровому ПК із шістнадцятковим процесором, і саме тут ми отримуємо свої перші випуски.

Я вперше пристосував код для роботи в Windows, оскільки саме цим користувався ігровий ПК, але із сумом виявив, що процес отримував лише близько 15% потужності центрального процесора. Я зрозумів, що це, мабуть, Windows, а не Windows, тому я завантажив живий компакт-диск Ubuntu, думаючи, що Ubuntu дозволить запустити процес із повним потенціалом, як це було раніше на моєму ноутбуці.

Однак я отримав лише 5% використання! Отже, моє питання полягає в тому, як я можу адаптувати програму для запуску на моєму ігровому автоматі або в Windows 7, або в живій Linux зі 100% завантаженням центрального процесора? Ще одне, що було б чудово, але не потрібно, - якщо кінцевим продуктом може бути один .exe, який можна легко розповсюджувати та запускати на машинах Windows.

Дуже дякую!

PS Звичайно, ця програма насправді не працювала зі спеціалізованими процесорами Crays 8, і це вже зовсім інше питання ... Якщо ви щось знаєте про оптимізацію коду для роботи на супер-комп’ютерах Cray 90-х, теж нам крикніть!


8
Не можу повірити, що немає тегу unicos . ;)
Едвард Томсон,

32
Дивно, що ця
однопотокова

24
Хіба я єдиний, кому це питання зовсім не цікаве? Давайте, запустіть одну різьбову програму на n-ядерній машині і запитайте, чому вона використовує 1 / n процесора, це просто ... неважливо, я просто проти :-)
Gunther Piez

16
@drhirsch Ну, питання показує наукові зусилля. Я поставив за це +1 - навіть якщо в OP не вистачає чогось фундаментального щодо багатоядерних обчислень.
Містичний

9
@drhirsch На сайті багато цікавих питань. Однак цікаво чи ні - це суб'єктивно. Можливо, йому бракує основних принципів, а це не суб’єктивно. Як сказав Містік, він справді демонструє зусилля в дослідженні і не так просто відповісти, як здається.
Карл

Відповіді:


81

Якщо ви хочете 100% процесора, вам потрібно використовувати більше 1 ядра. Для цього вам потрібно кілька потоків.

Ось паралельна версія за допомогою OpenMP:

Мені довелося збільшити ліміт, щоб 1000000на моїй машині зайняло більше 1 секунди.

Вихід:

Ця машина розрахувала всі 78498 простих чисел менше 1000000 за 29,753 секунди

Ось ваш 100% процесор:

введіть тут опис зображення


1
@ cha0site Так, я в основному відповідав на питання щодо ігрового автомата. Безумовно, є більш цікаві способи прив’язки процесора. Одним із найвідоміших тестів, які я зробив, є моя відповідь на це питання - яке перегріло 2 з 4 машин, які я протестував.
Містичний

1
@Mystical Offtopic: Яке обладнання ви використовуєте? My Hex-Core AMD @ 3.2Ghz зробив це за 92 секунди ...
bag-man

1
@Owen: У нього Core i7 2600K ... Я заздрю.
cha0site

19
Ой! Занадто ... набагато ... рожевий!
Mateen Ulhaq

2
@MohammadFadin en.wikipedia.org/wiki/Parallel_computing В основному, ви повинні мати можливість обробляти кілька завдань паралельно, щоб мати можливість використовувати багатоядерний комп'ютер.
Містичний

24

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

Рішення досить просте, оскільки ви просто намагаєтеся прив’язати процесор - якщо у вас N ядер, запустіть програму N разів (звичайно, паралельно).

Приклад

Ось код, який NUM_OF_CORESпаралельно запускає програму . Це POSIXy код - він використовує fork- тому вам слід запустити його під Linux. Якщо те, що я читаю про Cray, є правильним, можливо, буде простіше перенести цей код, ніж код OpenMP в іншій відповіді.

Вихідні дані


А-а, як коли вам потрібно запустити Prime95, у вас є кілька екземплярів ... Звичайно, є спосіб, щоб один процес використовував кілька ядер? Як і програми злому хеш-файлів.
bag-man

Ну, один процес міг би використовувати потоки для багатопроцесорної обробки, але я не думаю, що це те, що ви мали на увазі, оскільки нитка - це майже окремий процес у цьому контексті. Тут насправді йдеться про "керівників виконання", будь то потоки чи процеси. Отже, ні, немає способу змусити однопотокову програму працювати на декількох ядрах, її потрібно переписати. А іноді це справді важко. А іноді це насправді неможливо.
cha0site

Ну, я думаю, це буде не так важко, як змусити програму працювати і для Cray. Враховуючи, що я досить новачок у цьому (Що мене віддало: P), де було б гарним місцем для початку?
bag-man

@Owen: Ну, UNICOSсхоже, це чимось схоже на Unix (Вікіпедія все одно змушує так думати), тому, мабуть, так і є fork(). Вам слід піти навчитися користуватися цим, я думаю.
cha0site

2
Ооо! +1, коли у вас є приклад. :)
Містичний

7

ми дуже хочемо побачити, як швидко це може йти!

Ваш алгоритм генерації простих чисел дуже неефективний. Порівняйте це з primegen, який генерує прості числа 50847534 до 1000000000 всього за 8 секунд на Pentium II-350.

Щоб легко споживати всі процесори, ви можете вирішити незручно паралельну проблему, наприклад, обчислити набір Мандельброта або скористатися генетичним програмуванням, щоб намалювати Мона Лізу в декількох потоках (процесах).

Інший підхід - взяти існуючу контрольну програму для суперкомп’ютера Cray і перенести її на сучасний ПК.


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

5

Причиною того, що ви отримуєте 15% на шестигранному процесорі, є те, що ваш код використовує 1 ядро ​​на 100%. 100/6 = 16,67%, що з використанням ковзного середнього з плануванням процесу (ваш процес працював би за нормальним пріоритетом) можна легко повідомити як 15%.

Отже, для того, щоб використовувати 100% процесор, вам потрібно було б використовувати всі ядра вашого центрального процесора - запустити 6 паралельних шляхів виконання коду для шестигранного центрального процесора і мати цей масштаб аж до кількості процесорів, які має ваша машина Cray :)


Проблема цього полягає в тому, що як я можу отримати чіткий показник швидкості роботи кожної машини? Крім того, у Cray, мабуть, є "векторні процесори", тому для його нормальної роботи потрібне навантаження більше, ніж це
bag-man

Не знаю. Можливо, відмінності в процесах планування.
Карл

2

Також добре знайте, як ви завантажуєте центральний процесор. Процесор може виконувати багато різних завдань, і хоча багато хто з них буде повідомлено як "завантаження процесора на 100%", кожен з них може використовувати 100% різних частин процесора. Іншими словами, дуже важко порівняти два різних ЦП за продуктивністю, і особливо дві різні архітектури ЦП. Виконання завдання A може надавати перевагу одному центральному процесору над іншим, а виконуючи завдання B - може бути навпаки (оскільки ці два процесори можуть мати різні ресурси всередині і можуть виконувати код по-різному).

Ось чому програмне забезпечення так само важливо для забезпечення оптимальної роботи комп’ютерів, як і апаратне забезпечення. Це справді дуже актуально і для "суперкомп'ютерів".

Одним показником продуктивності процесора можуть бути інструкції в секунду, але знову ж таки інструкції не створюються рівними на різних архітектурах процесора. Ще одним показником може бути продуктивність кешування вводу-виводу, але інфраструктура кешування теж не є рівною. Тоді мірою може бути кількість інструкцій на використаний ват, оскільки подача та розсіювання енергії часто є обмежуючим фактором при проектуванні кластерного комп'ютера.

Тож першим вашим запитанням має бути: Який параметр ефективності для вас важливий? Що ви хочете виміряти? Якщо ви хочете побачити, яка машина отримує найбільше FPS у Quake 4, відповідь проста; ваша ігрова установка буде, оскільки Cray взагалі не може запустити цю програму ;-)

Вітаю, Стін


2

TLDR; Прийнята відповідь є одночасно неефективною та несумісною. Наступний алго працює в 100 разів швидше.

Компілятор gcc, доступний на MAC, не може працювати omp. Мені довелося встановити llvm (brew install llvm ). Але я не бачив, що простой процесора падав під час запуску версії OMP.

Ось знімок екрана під час запуску версії OMP. введіть тут опис зображення

Крім того, я використовував базовий потік POSIX, який можна запустити за допомогою будь-якого компілятора c, і побачив, що майже весь процесор витрачається, коли nos of thread= no of cores= 4 (MacBook Pro, 2,3 ГГц Intel Core i5). Ось програма -

Зверніть увагу, як витрачений весь процесор - введіть тут опис зображення

PS - Якщо ви не збільшуєте кількість потоків, фактичне використання центрального процесора зменшується (спробуйте вказати кількість потоків = 20.), оскільки система використовує більше часу на перемикання контексту, ніж фактичні обчислення.

До речі, моя машина не така міцна, як @mystical (Прийнята відповідь). Але моя версія з базовими потоковими потоками POSIX працює набагато швидше, ніж OMP. Ось результат -

введіть тут опис зображення

PS Збільште навантаження потоків до 2,5 мільйонів, щоб побачити використання процесора, оскільки воно завершується менш ніж за секунду.


0

Спробуйте розпаралелювати вашу програму, використовуючи, наприклад, OpenMP. Це дуже проста та ефективна основа для складання паралельних програм.


0

Для швидкого вдосконалення одного ядра видаліть системні дзвінки, щоб зменшити перемикання контексту. Видаліть ці рядки:

Перший особливо поганий, оскільки він породжує новий процес на кожній ітерації.


0

Просто спробуйте заархівувати та розпакувати великий файл, ніщо, як важкі операції вводу-виводу, не може використовувати процесор.

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