Як отримати 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.